如何使用Pivot或Case语句在SQL中实现行转列
SQL行转列实现方案(将condition字段展开为多列)
源数据表
| ID | condition | start time | end time |
|---|---|---|---|
| M01 | baseline | 15/06/2018 | 16/04/2015 |
| M01 | tactical | 03/04/2001 | 06/12/2017 |
| M02 | tactical | 30/06/2007 | 18/08/2002 |
| M02 | baseline | 19/07/2001 | 06/09/2007 |
| M03 | baseline | 09/12/2015 | 30/07/2014 |
| M03 | tactical | 17/07/2002 | 09/05/2009 |
目标数据表
| ID | baseline start time | baseline end time | tactical start time | tactical end time |
|---|---|---|---|---|
| M01 | 15/06/2018 | 16/04/2015 | 03/04/2001 | 06/12/2017 |
| M02 | 19/07/2001 | 06/09/2007 | 30/06/2007 | 18/08/2002 |
| M03 | 09/12/2015 | 30/07/2014 | 17/07/2002 | 09/05/2009 |
实现方案1:使用CASE语句(通用型,适配多数数据库)
CASE是兼容性最强的行转列方式,不依赖特定数据库的PIVOT语法,适合跨数据库场景。
SELECT ID, MAX(CASE WHEN condition = 'baseline' THEN `start time` END) AS `baseline start time`, MAX(CASE WHEN condition = 'baseline' THEN `end time` END) AS `baseline end time`, MAX(CASE WHEN condition = 'tactical' THEN `start time` END) AS `tactical start time`, MAX(CASE WHEN condition = 'tactical' THEN `end time` END) AS `tactical end time` FROM your_table_name GROUP BY ID;
核心逻辑
- 用
CASE判断condition字段值,分别提取对应时间列的内容 - 配合
MAX聚合函数,将同一ID的多条记录合并为一行 - 替换
your_table_name为实际表名即可执行
实现方案2:使用PIVOT(以SQL Server为例)
如果使用支持PIVOT语法的数据库(如SQL Server、Oracle),可以用以下写法:
SELECT ID, [baseline_start] AS `baseline start time`, [baseline_end] AS `baseline end time`, [tactical_start] AS `tactical start time`, [tactical_end] AS `tactical end time` FROM ( SELECT ID, CONCAT(condition, '_start') AS time_type, `start time` AS time_value FROM your_table_name UNION ALL SELECT ID, CONCAT(condition, '_end') AS time_type, `end time` AS time_value FROM your_table_name ) AS src PIVOT ( MAX(time_value) FOR time_type IN ([baseline_start], [baseline_end], [tactical_start], [tactical_end]) ) AS pvt;
核心逻辑
- 先通过
UNION ALL将start time和end time合并为同一列,同时标记对应的类型(如baseline_start) - 再用
PIVOT将类型字段转换为列,通过聚合函数提取对应值
内容的提问来源于stack exchange,提问作者elokema
相关产品推荐
相关产品推荐

