SQL如何实现多行记录分组转列、按发票号合并聚合数据
行转列分组合并解决方案
你要实现的是典型的**行转列(透视)**需求,以下是不同场景的可行方案:
通用SQL实现(兼容所有关系型数据库)
你之前用GROUP BY未达到效果,是因为没有结合聚合逻辑过滤对应列的值,写法如下:
SELECT InvoiceNumber, MAX(CASE WHEN `Column` = 'Column A1' THEN Value END) AS ColumnA1, MAX(CASE WHEN `Column` = 'Column A2' THEN Value END) AS ColumnA2, MAX(CASE WHEN `Column` = 'Column A3' THEN Value END) AS ColumnA3, MAX(CASE WHEN `Column` = 'Column B1' THEN Value END) AS ColumnB1, MAX(CASE WHEN `Column` = 'Column B2' THEN Value END) AS ColumnB2 FROM 你的表名 GROUP BY InvoiceNumber;
逻辑说明:CASE WHEN语句会匹配对应列名的行返回Value,不匹配的行返回NULL,MAX聚合函数会跳过NULL值,最终拿到每个InvoiceNumber下各列对应的唯一值,完全符合你需要的输出结果。
主流数据库简化写法
- MySQL:可将CASE WHEN替换为IF函数简化代码,单值场景通用写法可直接运行
- SQL Server / Oracle:支持PIVOT关键字直接实现透视,示例SQL Server写法:
SELECT * FROM ( SELECT InvoiceNumber, [Column], Value FROM 你的表名 ) AS SourceTable PIVOT ( MAX(Value) FOR [Column] IN ([Column A1], [Column A2], [Column A3], [Column B1], [Column B2]) ) AS PivotTable;
- PostgreSQL:可使用crosstab函数实现更简洁的透视逻辑
动态列适配方案
如果你的Column值是动态增加的,不需要每次手动修改查询语句,可以使用动态SQL拼接生成查询逻辑,示例MySQL动态写法:
SET @sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT('MAX(CASE WHEN `Column` = ''', `Column`, ''' THEN Value END) AS `', REPLACE(`Column`, ' ', ''), '`') ) INTO @sql FROM 你的表名; SET @sql = CONCAT('SELECT InvoiceNumber, ', @sql, ' FROM 你的表名 GROUP BY InvoiceNumber'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
内容的提问来源于stack exchange,提问作者ItsMeGokul
相关产品推荐
相关产品推荐

