【问题标题】:Concatenate Multiple rows of a table in SQL Server 2014 / SQL Server 2016 [duplicate]在 SQL Server 2014 / SQL Server 2016 中连接表的多行 [重复]
【发布时间】:2020-01-07 07:31:30
【问题描述】:

我有一张这样的桌子:

 id  | movie   | actorid | actor   | roleid | rolename
 ----+---------+---------+---------+--------+------------------
 1   |  mi3    |  121    | tom     |   6    |  actor
 2   | avenger |  104    | scarlett|   4    |  actress
 2   | avenger |  3      | russo   |   2    |  action director

我期待这样的输出:

id  | movie   | actorid |      actor     | roleid | rolename
----+---------+---------+----------------+--------+--------------------------
1   |  mi3    |  121    | tom            |   6    |  actor
2   | avenger |  104,3  | scarlett,russo |   4,2  |  actress, action director

对于最新的 SQL Server 版本,我看到了 STRING_AGG 函数来连接列或行数据。但是如何使用STUFF 实现 SQL Server 2014 的预期输出?

【问题讨论】:

  • 使用FOR XML PATH。大量相关问题
  • 我个人建议不要这样做。您的数据最终会变得非常混乱,并且 SQL Server 没有(本机)分隔字符串中的序数位置的概念。
  • 嗨拉努,谢谢你的建议。实际上,我想在 标记中显示每条记录。在 foreach 循环中。而且这个数据是有限的,比如大约 142 行 ..

标签: sql-server tsql string-aggregation


【解决方案1】:

试试这个:

DECLARE @DataSource TABLE
(
    [id] INT
   ,[movie] VARCHAR(12)
   ,[actiorid] INT
   ,[actor] VARCHAR(12)
   ,[roleid] INT
   ,[rolename] VARCHAR(36)
);

INSERT INTO @DataSource ([id], [movie], [actiorid], [actor], [roleid], [rolename])
VALUES (1, 'mi3 ', 121, 'tom ', 6, 'actor')
      ,(2, 'avenger', 104, 'scarlett', 4, 'actress')
      ,(2, 'avenger', 3, 'russo', 2, 'action director');

-- SQL Server 2017
SELECT [id] 
      ,[movie]
      ,STRING_AGG([actiorid], ',') AS [actorid]
      ,STRING_AGG([actor], ',') AS [actor]
      ,STRING_AGG([roleid], ',') AS [roleid]
      ,STRING_AGG([rolename], ',') AS [rolename]
FROM @DataSource
GROUP BY [id]
        ,[movie];

-- SQL Server
WITH DataSoruce AS
(
    SELECT DISTINCT [id] 
                   ,[movie]
    FROM @DataSource
)
SELECT *
FROM DataSoruce A
CROSS APPLY
(
    SELECT STUFF
    (
        (
            SELECT DISTINCT ',' + CAST([actiorid] AS VARCHAR(12))
            FROM @DataSource S
            WHERE A.[id] = S.[id]
                AND A.[movie] = S.[movie]
            FOR XML PATH, TYPE 
        ).value('.', 'VARCHAR(MAX)')
        ,1
        ,1
        ,''
    )
) R1 ([actiorid])
CROSS APPLY
(
    SELECT STUFF
    (
        (
            SELECT DISTINCT ',' + CAST([actor] AS VARCHAR(12))
            FROM @DataSource S
            WHERE A.[id] = S.[id]
                AND A.[movie] = S.[movie]
            FOR XML PATH, TYPE 
        ).value('.', 'VARCHAR(MAX)')
        ,1
        ,1
        ,''
    )
) R2 ([actor])
CROSS APPLY
(
    SELECT STUFF
    (
        (
            SELECT DISTINCT ',' + CAST([roleid] AS VARCHAR(12))
            FROM @DataSource S
            WHERE A.[id] = S.[id]
                AND A.[movie] = S.[movie]
            FOR XML PATH, TYPE 
        ).value('.', 'VARCHAR(MAX)')
        ,1
        ,1
        ,''
    )
) R3 ([roleid])
CROSS APPLY
(
    SELECT STUFF
    (
        (
            SELECT DISTINCT ',' + CAST([rolename] AS VARCHAR(12))
            FROM @DataSource S
            WHERE A.[id] = S.[id]
                AND A.[movie] = S.[movie]
            FOR XML PATH, TYPE 
        ).value('.', 'VARCHAR(MAX)')
        ,1
        ,1
        ,''
    )
) R4 ([rolename]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-31
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多