MySQL查询咨询:将状态数据行转列展示的实现方法
实现MySQL行转列(状态转时间列)的查询方案
刚好碰到过类似的需求,这本质是把行数据转成列的经典场景,用MySQL的条件聚合就能轻松解决。先理清楚你的需求细节:
原表table1查询结果
| id | time | date | Status |
|---|---|---|---|
| 1 | 07:30:00 | 2019-06-19 | 0 |
| 1 | 11:30:00 | 2019-06-19 | 1 |
| 1 | 13:00:00 | 2019-06-19 | 2 |
| 1 | 16:30:00 | 2019-06-19 | 3 |
| 2 | 08:10:00 | 2019-06-19 | 0 |
| 2 | 12:03:00 | 2019-06-19 | 1 |
| 2 | 13:01:00 | 2019-06-19 | 2 |
| 2 | 16:15:00 | 2019-06-19 | 3 |
期望输出格式
| id | Date | Checkin | Breakout | Breakin | Checkout |
|---|---|---|---|---|---|
| 1 | 2019-06-19 | 07:30:00 | 11:30:00 | 13:00:00 | 16:30:00 |
| 2 | 2019-06-19 | 08:10:00 | 12:03:00 | 13:01:00 | 16:15:00 |
对应的SQL查询语句
SELECT id, date AS `Date`, MAX(CASE WHEN Status = 0 THEN time END) AS `Checkin`, MAX(CASE WHEN Status = 1 THEN time END) AS `Breakout`, MAX(CASE WHEN Status = 2 THEN time END) AS `Breakin`, MAX(CASE WHEN Status = 3 THEN time END) AS `Checkout` FROM table1 GROUP BY id, date ORDER BY id;
逻辑说明
- 分组聚合:通过
GROUP BY id, date把同一个用户(id)同一天的所有状态记录合并到一行 - 条件匹配取值:每个
CASE语句会筛选对应状态的时间,不匹配的记录会返回NULL - 提取有效数据:
MAX()函数会从每组的结果中取出非NULL的时间值(因为每个id+date下每个状态只会有一条有效记录,用MIN()也能达到同样效果)
如果后续新增了其他状态,只需要按照同样的格式添加新的MAX(CASE ...)语句即可,扩展性很强。
内容的提问来源于stack exchange,提问作者Hip Hura
相关产品推荐
相关产品推荐

