SQL数据库行转列问询:如何将考勤状态数据转换为宽表格式
解决行转列的SQL查询方案
这是个很典型的行转列场景,你之前用GROUP BY出错,大概率是因为没有对time列使用聚合函数处理——GROUP BY之后,所有非分组字段都需要用聚合函数包裹,数据库才知道如何合并同一分组下的多条记录值。下面给你两种实用的解决方案:
方法一:CASE表达式结合聚合函数(通用所有SQL数据库)
这是兼容性最强的写法,几乎所有关系型数据库都支持:
SELECT ID, date, MAX(CASE WHEN STATUS = 'IN' THEN time END) AS "IN", MAX(CASE WHEN STATUS = 'OUT' THEN time END) AS "OUT" FROM your_table_name -- 替换成你的实际表名 GROUP BY ID, date ORDER BY date;
逻辑说明:
GROUP BY ID, date把同一ID、同一日期的记录归为一组;CASE语句会筛选出当前分组下状态为IN/OUT的时间值;- 用
MAX()(或MIN(),因为每组里每个状态只会对应一个时间值)聚合,就能把两个状态的时间提取到同一行的不同列中。
方法二:使用PIVOT语法(适用于支持该特性的数据库)
如果你的数据库是SQL Server、Oracle、PostgreSQL(11+)这类支持PIVOT的,可以用更简洁的语法:
SELECT ID, date, "IN", "OUT" FROM your_table_name -- 替换成你的实际表名 PIVOT ( MAX(time) -- 聚合函数,这里用MAX/MIN都可以 FOR STATUS IN ("IN", "OUT") -- 指定要转成列的状态值 ) AS PivotResult ORDER BY date;
这两种方法都能得到你想要的结果格式,把每天的IN、OUT时间合并到同一行。
内容的提问来源于stack exchange,提问作者mr.jm
相关产品推荐
相关产品推荐

