【问题标题】:How to concatenate many rows with same id in sql?如何在sql中连接具有相同id的多行?
【发布时间】:2016-05-12 09:48:03
【问题描述】:

我的表格包含两个字段的详细信息:

ID      DisplayName
1        Editor
1        Reviewer
7        EIC
7        Editor
7        Reviewer
7        Editor
19       EIC
19       Editor
19       Reviewer

我想通过 DisplayName 获取独特的详细信息,例如

1 Editor,Reviewer 7 EIC,Editor,Reviewer

不要得到 ID 为 7 的重复值

如何结合DisplayName Details?如何编写查询?

【问题讨论】:

  • 是哪一个? mysql 还是 sql-server?
  • @sagi: 我的意思是 sql server
  • 您现在想拥有 2 列吗? IDDisplayName 只是为了同一个 id 你想要逗号分开的名字?或者你想在你写的一行中得到所有结果?
  • @StanislovasKalašnikovas:我想获得所有结果,但我不需要获得重复值。 ID = 7 我有 2 个编辑器,但我想要一个。

标签: sql sql-server


【解决方案1】:

SQL-Server 中,您可以执行以下操作:

查询

SELECT id, displayname = 
    STUFF((SELECT DISTINCT ', ' + displayname
           FROM #t b 
           WHERE b.id = a.id 
          FOR XML PATH('')), 1, 2, '')
FROM #t a
GROUP BY id

测试数据

create table #t 
(
id int,
displayname nvarchar(max)
)

insert into #t values    
 (1 ,'Editor')
,(1 ,'Reviewer')
,(7 ,'EIC')
,(7 ,'Editor')
,(7 ,'Reviewer')
,(7 ,'Editor')
,(19,'EIC')
,(19,'Editor')
,(19,'Reviewer')

输出

id  displayname
1   Editor, Reviewer
7   Editor, EIC, Reviewer
19  Editor, EIC, Reviewer

【讨论】:

  • , 1, 2, '' 后面的意思是什么?
  • @guradio 这是删除开头的逗号和空格,否则会出现。它们是STUFF 的参数:start = 1,length = 2,replacement value = '',即。 前两个字符被替换为''
【解决方案2】:
DECLARE @t TABLE
(
    ID INT,
    DisplayName VARCHAR(50)
)
INSERT INTO @t (ID, DisplayName)
VALUES
    (1 , 'Editor'),
    (1 , 'Reviewer'),
    (7 , 'EIC'),
    (7 , 'Editor'),
    (7 , 'Reviewer'),
    (7 , 'Editor'),
    (19, 'EIC'),
    (19, 'Editor'),
    (19, 'Reviewer')

SELECT *, STUFF((
            SELECT DISTINCT ', ' + DisplayName
            FROM @t
            WHERE ID = t.ID
            FOR XML PATH('')), 1, 2, '')
FROM (
    SELECT DISTINCT ID
    FROM @t
) t

输出 -

----------- ------------------------
1           Editor, Reviewer
7           Editor, EIC, Reviewer
19          Editor, EIC, Reviewer

我关于字符串聚合的帖子:

http://www.codeproject.com/Articles/691102/String-Aggregation-in-the-World-of-SQL-Server

【讨论】:

  • , 1, 2, '' 后面的意思是什么?
  • 终于可以使用这个示例了。只需将 @t 替换为类似于临时表的子选择即可!
【解决方案3】:

对于 MySQL:
SELECT id, GROUP_CONCAT(displayname) FROM tableName GROUP BY id

参考:http://www.sqlines.com/mysql/functions/group_concat

【讨论】:

  • SQL-Server 不支持这种表示法。
  • 谢谢,效果很好。我希望我们可以更改分隔符!
【解决方案4】:

SQL Server 2017+ 和 SQL Azure:STRING_AGG

从 SQL Server 的下一个版本开始,我们终于可以跨行连接,而无需求助于任何变量或 XML 巫术。

STRING_AGG (Transact-SQL)

SELECT ID, STRING_AGG(DisplayName, ', ') AS DisplayNames
FROM TableName
GROUP BY ID

【讨论】:

    【解决方案5】:

    如果是oracle数据库

    select id, 
           listagg(displayname, ',') within group (order by displayname) as names
    from test
    group by id 
    

    【讨论】:

      【解决方案6】:

      谢谢大家,

      SELECT Distinct
          t1.ID,
          MAX(STUFF(t2.x_id,1,1,'')) AS DisplayName
      FROM Table t1
      CROSS apply(
          SELECT Distinct ', ' + SUBSTRING(t2.DisplayName,1,2)
          FROM Table t2
          WHERE t2.ID = t1.ID AND t2.DisplayName > ''
          FOR xml PATH('')
      ) AS t2 (x_id)
      GROUP BY
          t1.ID
      order by 1
      GO
      

      【讨论】:

      • 只是让你知道。当表中有很多行时,这种方法会比德瓦特和斯坦的答案慢得多
      • , 1, 2, '' 后面的意思是什么?
      【解决方案7】:

      更改分隔符使用

      SELECT id, GROUP_CONCAT(displayname SEPARATOR ';') FROM tableName GROUP BY id
      

      这会将分隔符从逗号更改为分号:)

      【讨论】:

        猜你喜欢
        • 2023-04-11
        • 2018-06-03
        • 2016-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-25
        • 2022-12-14
        相关资源
        最近更新 更多