首页 > 数据库 > mysql教程 > 如何在 SQL 中高效地跨逗号分隔列连接数据?

如何在 SQL 中高效地跨逗号分隔列连接数据?

DDD
发布: 2024-12-28 00:24:10
原创
804 人浏览过

How to Efficiently Join Data Across Comma-Delimited Columns in SQL?

连接逗号分隔的数据列

逗号分隔值 (CSV) 通常用于在单个列中存储多个值关系数据库。然而,这种格式在执行数据操作任务时可能会带来挑战。本文探讨了跨逗号分隔列连接数据的技术。

示例场景

考虑以下两个表:

表 1 (T1)

col1 col2
C1 john
C2 alex
C3 piers
C4 sara

表 2 (T2)

col1 col2
R1 C1,C2,C4
R2 C3,C4
R3 C1,C4

期望输出:

col1 col2
R1 john,alex,sara
R2 piers,sara
R3 john,sara

最优归一化性能

理想情况下,数据应该标准化,消除表 2 中的逗号分隔值。通过创建具有以下结构的新表:

CREATE TABLE T2 (
    col1 varchar(2),
    col2 varchar(2),
    PRIMARY KEY (col1, col2),
    FOREIGN KEY (col2) REFERENCES T1 (col1)
);
登录后复制

可以插入数据相应地,实现高效的连接:

INSERT INTO T2 (col1, col2) VALUES ('R1', 'C1'), ('R1', 'C2'), ('R1', 'C4'), ('R2', 'C3'), ('R2', 'C4'), ('R3', 'C1'), ('R3', 'C4');
登录后复制

直接查询连接:

使用规范化表,简单的连接可以检索所需的数据:

SELECT t2.col1, t1.col2
FROM t2
INNER JOIN t1
ON t2.col2 = t1.col1;
登录后复制

连接逗号分隔的输出:

如果所需的输出需要逗号分隔值,则可以使用 FOR XML PATH 和 STUFF 函数使用:

SELECT DISTINCT t2.col1, 
STUFF(
    (SELECT DISTINCT ', ' + t1.col2
    FROM t1
    INNER JOIN t2 t ON t1.col1 = t.col2
    WHERE t2.col1 = t.col1
    FOR XML PATH ('')), 1, 1, '') AS col2
FROM t2;
登录后复制

非标准化数据的分割函数:

在没有标准化数据的情况下,可以创建一个分割函数来将逗号分隔的值分成单独的值rows:

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;
登录后复制

在 CTE(通用表表达式)中使用 split 函数,数据可以处理:

WITH CTE AS
(
  SELECT c.col1, t1.col2
  FROM t1
  INNER JOIN 
  (
    SELECT t2.col1, i.items AS 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, '') AS col2
FROM CTE c
登录后复制

替代 FOR XML PATH 查询:

另一种方法涉及直接应用 FOR XML PATH:

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;
登录后复制

结论

跨界加入逗号分隔的数据需要仔细考虑性能和输出格式。规范化可提供最佳性能,但如果不可行,则拆分函数或直接 FOR XML PATH 查询可提供替代方案。这些技术可以从逗号分隔的列中进行高效的数据操作和检索。

以上是如何在 SQL 中高效地跨逗号分隔列连接数据?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板