3 votes

Fixation de la relation ManyToMany

J'ai la configuration de base de données suivante :

CREATE TABLE `categories` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
)

CREATE TABLE `items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `category_ids` varchar(50) NOT NULL,
  PRIMARY KEY (`id`)
)

dans laquelle category_ids est une chaîne d'identifiants de catégories séparés par des virgules : 1, 10, 15, 6 . Existe-t-il un moyen de convertir cette base de données en une base plus conventionnelle (utilisant trois tables, dont une pour stocker les relations), en utilisant uniquement SQL et aucun autre scripts ?

1voto

MatBailie Points 37610

MySQL ne dispose pas de CROSS APPLY ou de CTE récursifs, qui seraient les voies les plus simples.

Mais vous ne le faites qu'une fois, donc vous n'avez besoin que d'un petit coup de pouce.

Tout d'abord, trouvez le nombre maximum d'éléments dans la liste des catégories...

SELECT
  MAX(LEN(category_ids) - LEN(REPLACE(category_ids, ',', '')) + 1) AS max_items
FROM
  items

Alors vous pouvez faire quelque chose comme ça...

SELECT
  items.id,
  SUBSTRING_INDEX(
    SUBSTRING_INDEX(
      items.category_ids,
      ',',
      map.id  -- Get the first 'n' items from the list
    ),
    ',',
    -1        -- Get the last item from (the first 'n' items from the list)
  ) AS category_id
FROM
  items
INNER JOIN
(
            SELECT 1 as id
  UNION ALL SELECT 2 as id
  UNION ALL SELECT 3 as id
  etc, etc, up to the max number of items found previously
)
  AS map
    ON LEN(items.category_ids) - LEN(REPLACE(items.category_ids, ',', '')) + 1 >= map.id

Je ne l'ai pas testé, mais je suppose que SUBSTRING_INDEX('last', ',', -1) renvoie à 'last' .

Je ne suis pas un expert de MySQL, donc ce n'est peut-être pas optimal, mais pour un gain rapide, ce type de structure devrait fonctionner...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X