Maison >base de données >tutoriel mysql >Comment joindre efficacement des colonnes de données séparées par des virgules dans des bases de données ?

Comment joindre efficacement des colonnes de données séparées par des virgules dans des bases de données ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-27 16:07:10457parcourir

How to Efficiently Join Comma-Separated Data Columns in Databases?

Joindre une colonne de données séparées par des virgules : solutions approfondies

Dans les systèmes de bases de données, il est souvent nécessaire de manipuler des données stockées entre virgules. colonnes séparées. La normalisation des données dans plusieurs tables est une solution idéale, mais il existe des cas où cela peut ne pas être réalisable. Nous présentons ici différentes méthodes pour joindre efficacement des colonnes délimitées par des virgules.

Normalisation et jointures de tables

La normalisation des données dans des tables séparées est l'approche la plus efficace. Cela implique de créer un nouveau tableau avec une ligne pour chaque valeur unique dans la colonne séparée par des virgules. Les tables peuvent ensuite être jointes à l'aide d'une relation de clé étrangère.

-- T1 Table
CREATE TABLE T1
(
  col1 varchar(2), 
  col2 varchar(5),
  constraint pk1_t1 primary key (col1)
);

-- T2 Table
CREATE TABLE T2
(
  col1 varchar(2), 
  col2 varchar(2),
  constraint pk1_t2 primary key (col1, col2),
  constraint fk1_col2 foreign key (col2) references t1 (col1)
);

Une fois normalisées, les données peuvent être facilement interrogées à l'aide d'une jointure :

SELECT t2.col1, t1.col2
FROM t2
INNER JOIN t1
  ON t2.col2 = t1.col1

Fonction de fractionnement personnalisée pour Données non normalisées

Si la normalisation n'est pas possible, nous pouvons créer une fonction de fractionnement personnalisée pour convertir les données séparées par des virgules en lignes individuelles.

CREATE FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))       
RETURNS @temptable TABLE (items varchar(MAX))       
AS       
BEGIN      
    DECLARE @idx int       
    DECLARE @slice varchar(8000)       

    SELECT @idx = 1       
    IF LEN(@String)<1 OR @String IS NULL RETURN       

    WHILE @idx!= 0       
    BEGIN       
        SET @idx = CHARINDEX(@Delimiter,@String)       
        IF @idx!=0       
            SET @slice = LEFT(@String,@idx - 1)       
        ELSE       
            SET @slice = @String       

        IF(LEN(@slice)>0)  
            INSERT INTO @temptable(Items) VALUES(@slice)       

        SET @String = RIGHT(@String,LEN(@String) - @idx)       
        IF LEN(@String) = 0 BREAK       
    END   
RETURN 
END;

En utilisant cette fonction, nous pouvons joindre la table d'origine avec les données fractionnées :

;WITH cte AS
(
  SELECT c.col1, t1.col2
  FROM t1
  INNER JOIN 
  (
    SELECT t2.col1, i.items col2
    FROM t2
    CROSS APPLY dbo.split(t2.col2, ',') i
  ) c
    ON t1.col1 = c.col2
)
SELECT DISTINCT c.col1, 
  STUFF(
         (SELECT DISTINCT ', ' + c1.col2
          FROM cte c1
          WHERE c.col1 = c1.col1
          FOR XML PATH('')), 1, 1, '') col2
FROM cte c

POUR XML PATH Direct Application

Une autre méthode implique l’application directe du FOR XML PATH fonctionnalité :

SELECT col1, 
(
  SELECT ', '+t1.col2
  FROM t1
  WHERE ','+t2.col2+',' LIKE '%,'+CAST(t1.col1 AS VARCHAR(10))+',%'
  FOR XML PATH(''), TYPE
).value('SUBSTRING(TEXT()[1], 3)', 'VARCHAR(MAX)') AS col2
FROM t2;

Conclusion

La solution optimale dépend du scénario spécifique. La normalisation des données est l'option la plus efficace, mais si cela n'est pas réalisable, l'utilisation d'une fonction de fractionnement personnalisée ou l'application directe de FOR XML PATH peut fournir des résultats efficaces.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn