【问题标题】:SQL - Turn relationship IDs into a delimited listSQL - 将关系 ID 转换为分隔列表
【发布时间】:2016-04-20 08:55:57
【问题描述】:

假设我有一张包含以下数据的表格:

您可以看到 a、b 和 c 列有很多冗余。我希望在保留 site_id 信息的同时删除这些冗余。如果我从查询中排除 site_id 列,我可以通过执行SELECT DISTINCT a, b, c from my_table 获得部分路径。

理想的情况是 SQL 查询可以将与 a/b/c 排列相关的站点 ID 转换为分隔列表,并输出如下内容:

是否可以使用 SQL 查询来做到这一点?还是我必须导出所有内容并使用不同的工具来删除冗余?

数据在 SQL Server 数据库中,不过我也很好奇如何用 postgres 做同样的事情,如果过程不同的话。

【问题讨论】:

  • 对于 MSSQL,您有 COALESCE,对于 PostgreSQL,您有 string_agg,但取决于版本不同的方法。不要忘记搜索是你的朋友;)
  • 我知道一个简单的方法是 SQL 但不确定 postgres。 sqlandme.com/2011/04/27/…
  • 这是使用 SQL Server stackoverflow.com/a/1785923/215752 的一种方法
  • 哇,我认为我试图做的事情有点奇怪(并且没有多少运气搜索)......显然这并不是那么不寻常。我只是在寻找错误的东西。谢谢大家!

标签: sql sql-server postgresql


【解决方案1】:

对于 SQL Server,您可以使用在this 帖子中接受的答案中找到的 FOR XML 技巧。

对于您的场景,它看起来像这样:

SELECT a, b, c,  SiteIds = 
    STUFF((SELECT ', ' + SiteId
           FROM your_table t2 
           WHERE t2.a = t1.a AND t2.b = t1.b AND t2.c = t1.c
          FOR XML PATH('')), 1, 2, '')
FROM your_table t1
GROUP BY a, b, c

【讨论】:

    【解决方案2】:

    对于 Postgres:

    select a,b,c, string_agg(site_id::varchar, ',')
    from my_table
    group by a,b,b;
    

    我假设site_id 是一个数字,并且string_agg() 只接受字符值,因此需要将其转换为字符串以进行聚合。这就是site_id::text 所做的。或者,您可以使用cast() 运算符:string_agg(cast(site_id as varchar), ',')

    【讨论】:

      【解决方案3】:

      这通常称为字符串聚合。许多 RDBMS 具有内置的能力,而许多其他 RDBMS 则没有。

      在 Postgres 中,您只需使用 STRING_AGG(<field>, <delimiter>) 函数,并确保为您的非聚合字段添加 GROUP BY。简单的东西。

      在 SQL Server 中.. 不是很漂亮,但人们有一些功能和诸如此类的东西可以让你做到这一点 (like in this Q/A)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-24
        • 2010-09-29
        • 2017-11-12
        • 2021-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多