如何基于条件将查询数据合并为单行?SQL行转列需求
解决方案:用分组聚合+CASE语句实现行转列
你遇到的问题是典型的行转列场景,之前单独用CASE语句会生成多行,是因为没有对code1和code2进行分组,也没有用聚合函数把同一组的结果合并成单行。下面是具体的实现方案:
核心思路
我们需要按code1和code2分组,对每个目标状态(S1-S4):
- 用
CASE判断该状态是否作为new_status出现过,出现标记为1,否则为0 - 用聚合函数
MAX提取该状态对应的created_at(如果存在),否则填0 - 最终每个
code1+code2组合只会生成一行结果
完整SQL代码
假设你的表名为status_changes,执行以下查询:
SELECT code1, code2, -- S1 状态及对应日期 MAX(CASE WHEN new_status = 'S1' THEN 1 ELSE 0 END) AS S1, MAX(CASE WHEN new_status = 'S1' THEN created_at ELSE '0' END) AS S1_date, -- S2 状态及对应日期 MAX(CASE WHEN new_status = 'S2' THEN 1 ELSE 0 END) AS S2, MAX(CASE WHEN new_status = 'S2' THEN created_at ELSE '0' END) AS S2_date, -- S3 状态及对应日期 MAX(CASE WHEN new_status = 'S3' THEN 1 ELSE 0 END) AS S3, MAX(CASE WHEN new_status = 'S3' THEN created_at ELSE '0' END) AS S3_date, -- S4 状态及对应日期 MAX(CASE WHEN new_status = 'S4' THEN 1 ELSE 0 END) AS S4, MAX(CASE WHEN new_status = 'S4' THEN created_at ELSE '0' END) AS S4_date FROM status_changes GROUP BY code1, code2;
结果验证
执行后会得到你期望的格式:
| code1 | code2 | S1 | S1_date | S2 | S2_date | S3 | S3_date | S4 | S4_date |
|---|---|---|---|---|---|---|---|---|---|
| A | 1 | 0 | 0 | 1 | x | 1 | y | 1 | z |
| B | 2 | 0 | 0 | 0 | 0 | 1 | P | 0 | 0 |
注意事项
- 如果
created_at是日期类型,建议把ELSE后的'0'改成NULL,之后可以根据需求格式化为0(不同数据库的日期处理语法略有差异) - 如果同一
code1+code2组合存在重复的new_status记录,MAX会自动取最新的created_at,符合状态变更的逻辑
内容的提问来源于stack exchange,提问作者Hina M
相关产品推荐
相关产品推荐

