【问题标题】:SQL command to merge rows with common ID? [duplicate]用于合并具有公共 ID 的行的 SQL 命令? [复制]
【发布时间】:2014-01-28 19:30:40
【问题描述】:

我有一个看起来像这样的表:

Event ID  Name
1         Bob
1         Steve
1         Tom
2         Bob
3         Steve
3         Tom

有数千个事件 ID 和数十个唯一名称。我想要一个 SQL 查询来返回下表:

Event ID  Names
1         Bob, Steve, Tom
2         Bob
3         Steve, Tom

我正在寻找像 SUM()AVG() 这样的聚合函数,除了它连接字符串而不是做数学运算。

编辑:我无法在这台上使用 MS Access。

编辑 2:我意识到这在客户端语言中是微不足道的,但我正在尝试查看是否可以获得全 SQL 解决方案。

【问题讨论】:

  • 您使用的是哪种 DBMS? here 发布了一个类似的问题。 MySQL 有GROUP_CONCAT(),MSSQL 有STUFF(),Oracle 有LISTAGG()
  • 你说的是ORACLE吗? mysql?数据库服务器? DB2?
  • 在 MSSQL 中,这样做很痛苦,我通常最终会为连接进行 CLR 聚合。 PostgreSQL、Oracle 和 MySQL 很容易做到这一点。
  • 为什么要从 SQL 执行此操作(而不是仅使用“正常”JOIN 结果)? SQL 用于检索数据,而不是格式化。可以使用您选择的客户端语言轻松完成格式化。
  • @JeremyHolovacs 为什么说 MySQL 对此感到“痛苦”——GROUP_CONCAT 有问题吗?

标签: sql ms-access


【解决方案1】:

如果你使用的是 SQL 服务器,你可以这样做

SQL Fiddle Example

  WITH x AS
    (
      SELECT event_id FROM users
      GROUP BY event_id
    )
    SELECT x.event_id, 
           name = STUFF((SELECT ',' + name
                         FROM users WHERE event_id = x.event_id
                         FOR XML PATH('')), 1, 1, '')
    FROM x

【讨论】:

    【解决方案2】:

    您没有提及您使用的是哪个 DBMS,但在 MySQL 中这很容易:

    SELECT EventId, GROUP_CONCAT(Names)
    FROM MyTable
    GROUP BY EventId
    

    在 SQL Server 中,这有点棘手。我通常看到的解决方案要求您使用FOR XML PATH。你可以找到一篇关于如何做到这一点的好文章here

    【讨论】:

      【解决方案3】:

      在 PostgreSQL 中,这将是:

      select EventId, string_agg(name, ',') as names
      from the_table
      group by EventId;
      

      如果您希望名称在列表中排序:

      select EventId, string_agg(name, ',' order by name) as names
      from the_table
      group by EventId
      

      【讨论】:

      • 感谢您的建议;很高兴知道这在 PostgreSQL 中有效。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-27
      • 1970-01-01
      • 2023-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多