如何将表中NAME字段值转为独立列?CASE查询结果行数过多
解决CASE语句转列后多行合并为单行的问题
问题背景
使用CASE语句将表中NAME字段的值转换为独立列时,查询结果生成了多行,无法得到期望的单行聚合结果。
原始表数据
| NAME | VALUES |
|---|---|
| DATE | 2023-10-10T00:00:00 |
| NO | ABC2134832312 |
| MILEAGE | 6500 |
| CLASS | B |
| INITIAL | A |
当前使用的查询语句
SELECT id, CASE WHEN hdr_id = 7 THEN value END AS Date, CASE WHEN hdr_id = 8 THEN value END AS No, CASE WHEN hdr_id = 20 THEN value END AS mileage, CASE WHEN hdr_id = 18 THEN value END AS CLASS, CASE WHEN hdr_id = 19 THEN value END AS INITIAL FROM table WHERE hdr_id IN (7, 8, 18, 19, 20) AND id = 13
当前结果(多行)
| ID | DATE | NO | MILEAGE | CLASS | INITIAL |
|---|---|---|---|---|---|
| 13 | 2023-10-10T00:00:00 | ||||
| 13 | ABC2134832312 | ||||
| 13 | 6500 | ||||
| 13 | B | ||||
| 13 | A |
期望结果(单行)
| ID | DATE | NO | MILEAGE | CLASS | INITIAL |
|---|---|---|---|---|---|
| 13 | 2023/10/10 | ABC2134832312 | 6500 | B | A |
解决方案
核心是用**聚合函数(MAX/MIN)**包裹CASE表达式,并按id分组,这样就能将同一id的多行记录合并为单行,同时过滤掉CASE生成的NULL值。另外添加日期格式化函数满足日期格式需求。
修正后的SQL(MySQL示例)
SELECT id, DATE_FORMAT(CASE WHEN hdr_id = 7 THEN value END, '%Y/%m/%d') AS Date, MAX(CASE WHEN hdr_id = 8 THEN value END) AS No, MAX(CASE WHEN hdr_id = 20 THEN value END) AS mileage, MAX(CASE WHEN hdr_id = 18 THEN value END) AS CLASS, MAX(CASE WHEN hdr_id = 19 THEN value END) AS INITIAL FROM `table` WHERE hdr_id IN (7, 8, 18, 19, 20) AND id = 13 GROUP BY id
其他数据库适配说明
- Oracle/SQL Server:替换日期格式部分为
TO_CHAR(CASE WHEN hdr_id = 7 THEN value END, 'YYYY/MM/DD') - PostgreSQL:替换日期格式部分为
TO_CHAR(CASE WHEN hdr_id = 7 THEN value::DATE END, 'YYYY/MM/DD')
原理说明
- 聚合函数
MAX()会自动忽略NULL值,只保留每个CASE条件对应的有效字段值 GROUP BY id确保相同id的所有记录被聚合为单独一行
内容的提问来源于stack exchange,提问作者bing
相关产品推荐
相关产品推荐

