2

在 200,000 多条记录的 sqlserver 表中,我需要帮助更快地连接按其他列分组的某些列数据。例如,示例数据和预期结果如下所示

在这里,我需要将最后一列连接ColumnA, ColumnB, ColumnC为管道分隔的字符串,以便将这四列组合起来:

where KeyNumber=@strKeyNumber  and  Action=@strAction  and  Type=@strType  and  Code=@strCode

这四个是不同的组合。

我使用 t-sql STUFF 函数对此进行了编码,但它太慢了。我还使用 while 循环进行了不同的编码,但即使这样也太慢了。

所以我需要帮助来获得更快的结果。

这些列 A、B、C 中的数据是长字符串,因此连接的字符串应该是类型nvarchar(max)

表中的原始数据(某些列中可能存在重复):

ID  KeyNumber   Action  Type    Code    ColumnA     ColumnB     ColumnC  
1   1111111111  AC1     TYPE1   CODE1   ValueA1     ValueB1     ValueC1 
2   1111111111  AC1     TYPE1   CODE1   ValueA2     ValueB2     ValueC2 
3   1111111111  AC1     TYPE1   CODE1   ValueA2     ValueB2     ValueC3 
4   1111111111  AC1     TYPE1   CODE1   ValueA3     ValueB3     ValueC4
5   2222222222  AC2     TYPE2   CODE2   ValA1       ValB1       ValC1   
6   2222222222  AC2     TYPE2   CODE2   ValA2       ValB2       ValC2
7   2222222222  AC2     TYPE2   CODE2   ValA3       ValB3       ValC3
8   2222222222  AC2     TYPE2   CODE2   ValA4       ValB4       ValC4
9   2222222222  AC2     TYPE2   CODE2   ValA4       ValB5       ValC4   

需要将结果数据放入如下新表中(上表中的重复值不应在此重复):

ID  KeyNumber   Action  Type    Code    ColumnA                 ColumnB                         ColumnC  
1   1111111111  AC1     TYPE1   CODE1   ValueA1|ValueA2|ValueA3 ValueB1|ValueB2|ValueB3         ValueC1|ValueC2|ValueC3|ValueC4 
2   2222222222  AC2     TYPE2   CODE2   ValA1|ValA2|ValA3|ValA4 ValB1|ValB2|ValB3|ValB4|ValB5   ValC1|ValC2|ValC3|ValC4 
4

2 回答 2

2

你可以检查这个:

DECLARE @Table TABLE
(
    ID BIGINT,
    Keynumber BIGINT,
    [Action] CHAR(3),
    [Type] CHAR(5),
    Code CHAR(5),
    ColumnA NVARCHAR(MAX),
    ColumnB NVARCHAR(MAX),
    ColumnC NVARCHAR(MAX)
)

INSERT INTO @TABLE(ID,Keynumber,[Action],[Type],Code,ColumnA,ColumnB,ColumnC)
VALUES   (1,1111111111,'AC1','TYPE1','CODE1','ValueA1','ValueB1','ValueC1') 
        ,(2,1111111111,'AC1','TYPE1','CODE1','ValueA2','ValueB2','ValueC2')
        ,(3,1111111111,'AC1','TYPE1','CODE1','ValueA2','ValueB2','ValueC3')
        ,(4,1111111111,'AC1','TYPE1','CODE1','ValueA3','ValueB3','ValueC4')
        ,(5,2222222222,'AC2','TYPE2','CODE2','ValA1','ValB1','ValC1')
        ,(6,2222222222,'AC2','TYPE2','CODE2','ValA2','ValB2','ValC2')
        ,(7,2222222222,'AC2','TYPE2','CODE2','ValA3','ValB3','ValC3')
        ,(8,2222222222,'AC2','TYPE2','CODE2','ValA4','ValB4','ValC4')
        ,(9,2222222222,'AC2','TYPE2','CODE2','ValA4','ValB5','ValC4')

SELECT   Keynumber
        ,[Action]
        ,[Type]
        ,Code
        ,(
             SELECT  ColumnA AS [text()]
             FROM    @Table TableOne
             WHERE    TableOne.Keynumber = TableTwo.Keynumber and  TableOne.[Action] = TableTwo.[Action] and  TableOne.[Type] = TableTwo.[Type]
             ORDER BY TableOne.ColumnA
             FOR XML PATH(''), TYPE
        ).value('/', 'NVARCHAR(MAX)') AS ColumnA
        ,(
             SELECT  ColumnB AS [text()]
             FROM     @Table TableOne
             WHERE    TableOne.Keynumber = TableTwo.Keynumber and  TableOne.[Action] = TableTwo.[Action] and  TableOne.[Type] = TableTwo.[Type]
             ORDER BY TableOne.ColumnB
             FOR XML PATH(''), TYPE
        ).value('/', 'NVARCHAR(MAX)') AS ColumnB
        ,(
            SELECT   ColumnC AS [text()]
            FROM     @Table TableOne
            WHERE    TableOne.Keynumber = TableTwo.Keynumber and  TableOne.[Action] = TableTwo.[Action] and  TableOne.[Type] = TableTwo.[Type]
            ORDER BY TableOne.ColumnC
            FOR XML PATH(''), TYPE
        ).value('/', 'NVARCHAR(MAX)') AS ColumnC

FROM(
        SELECT  DISTINCT Keynumber,[Action],[Type],Code
        FROM    @Table
    ) TableTwo

另外,我不确定您使用的是哪种字符串连接方法。您可以查看此站点以了解其他技术:

http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/

于 2012-09-01T22:15:48.393 回答
1

您是否知道 CodePlex 具有用户定义的聚合GROUP_CONCAT的开源 CLR 实现。安装就像在您的服务器上运行 SQL 脚本一样简单。

http://groupconcat.codeplex.com/

它有 4 个 group_concat 实现并且是返回 NVARCHAR(MAX)

  • GROUP_CONCAT --默认分隔符是 ,(逗号)

  • GROUP_CONCAT_D -- 你可以指定分隔符

  • GROUP_CONCAT_DS - 您可以指定分隔符,排序顺序(1 为 asc 顺序,2 为 desc 顺序)

  • GROUP_CONCAT_S -- 你可以指定排序顺序

    我认为这在性能方面非常好。

在此处输入图像描述

在您的示例中,您将像这样使用它

SELECT   Keynumber
    ,[Action]
    ,[Type]
    ,Code
    ,dbo.GROUP_CONCAT_DS(ColumnA,'|',1) AS ColumnA
    ,dbo.GROUP_CONCAT_DS(ColumnB,'|',1) AS ColumnB
    ,dbo.GROUP_CONCAT_DS(ColumnC,'|',1) AS ColumnC 
FROM YourTable
GROUP BY
     Keynumber
    ,[Action]
    ,[Type]
    ,Code
于 2012-09-02T03:40:17.193 回答