You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写SQL查询实现数据表中值的归一化?

实现同一ID下的字符串聚合(行转列)

嘿,这个需求其实就是把同一id下的多个name值合并成逗号分隔的字符串,也就是常说的分组字符串聚合,核心逻辑很清晰:先按id字段分组,再对每个分组内的name字段进行字符串拼接。不同SQL方言的实现函数略有区别,我给你整理几个主流数据库的写法:

1. MySQL / MariaDB

用内置的GROUP_CONCAT()函数,这是最直接的写法:

SELECT 
    id,
    GROUP_CONCAT(name SEPARATOR ',') AS name
FROM 
    your_table_name  -- 替换成你的实际表名
GROUP BY 
    id;
  • 备注:SEPARATOR ','可以省略,因为默认就是用逗号分隔;如果需要去重,可改成GROUP_CONCAT(DISTINCT name)。

2. PostgreSQL

使用STRING_AGG()函数来完成聚合:

SELECT 
    id,
    STRING_AGG(name, ',') AS name
FROM 
    your_table_name
GROUP BY 
    id;
  • 备注:同样支持DISTINCT去重,比如STRING_AGG(DISTINCT name, ','),也可以通过ORDER BY指定拼接顺序,比如STRING_AGG(name, ',' ORDER BY name ASC)。

3. SQL Server

  • 2017及以上版本:支持STRING_AGG(),写法和PostgreSQL类似:
SELECT 
    id,
    STRING_AGG(name, ',') AS name
FROM 
    your_table_name
GROUP BY 
    id;
  • 2017以下版本:需要用FOR XML PATH的兼容写法:
SELECT 
    t.id,
    STUFF((SELECT ',' + name 
           FROM your_table_name 
           WHERE id = t.id 
           FOR XML PATH('')), 1, 1, '') AS name
FROM 
    your_table_name t
GROUP BY 
    t.id;
  • 备注:FOR XML PATH('')会把子查询的结果拼接成无标签的字符串,STUFF用来去掉开头多余的逗号。

4. Oracle

使用LISTAGG()函数,需要指定拼接顺序:

SELECT 
    id,
    LISTAGG(name, ',') WITHIN GROUP (ORDER BY name) AS name
FROM 
    your_table_name
GROUP BY 
    id;
  • 备注:WITHIN GROUP (ORDER BY ...)是必须的,用来定义name值的拼接顺序,你可以换成其他字段(比如ORDER BY id)或者自定义排序规则。

核心逻辑总结

不管用哪种数据库,核心都是两步:

  • 用GROUP BY id把相同ID的行归为一组
  • 调用对应数据库的字符串聚合函数,把组内的name值拼接成单个逗号分隔的字符串

内容的提问来源于stack exchange,提问作者Rahul Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:08:09