订阅更新

部门月收入行转列:12 个月变 12 列

SQL 实战 123 题 · 第 75 题 中等 约 2 分钟读完

LeetCode 1179 · 行转列、CASE + 聚合

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

按 id 分组,每个月一列 SUM(CASE WHEN month = 'Jan' THEN revenue END) AS Jan_Revenue,共 12 列。CASE 不写 ELSE,没数据的月份就是 NULL;如果月份是动态的,就要在程序里拼 SQL,或者用数据库自带的 PIVOT。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

题意

部门表每行是某部门某个月的收入(月份用 Jan、Feb 这样的缩写)。把它转成每个部门一行、每个月一列的宽表,没有数据的月份为空。

表结构

  • Department:id、revenue、month;(id, month) 为主键

思路

标准的行转列:按部门分组,每个月写一个 SUM(CASE month WHEN 'Jan' THEN revenue END),条件不满足时 CASE 返回 NULL,聚合后没有数据的月份就是 NULL。因为 (id, month) 唯一,SUM、MAX 都可以。

参考解法

SELECT id,
SUM(CASE `month` WHEN 'Jan' THEN revenue END) Jan_Revenue,
SUM(CASE `month` WHEN 'Feb' THEN revenue END) Feb_Revenue,
SUM(CASE `month` WHEN 'Mar' THEN revenue END) Mar_Revenue,
SUM(CASE `month` WHEN 'Apr' THEN revenue END) Apr_Revenue,
SUM(CASE `month` WHEN 'May' THEN revenue END) May_Revenue,
SUM(CASE `month` WHEN 'Jun' THEN revenue END) Jun_Revenue,
SUM(CASE `month` WHEN 'Jul' THEN revenue END) Jul_Revenue,
SUM(CASE `month` WHEN 'Aug' THEN revenue END) Aug_Revenue,
SUM(CASE `month` WHEN 'Sep' THEN revenue END) Sep_Revenue,
SUM(CASE `month` WHEN 'Oct' THEN revenue END) Oct_Revenue,
SUM(CASE `month` WHEN 'Nov' THEN revenue END) Nov_Revenue,
SUM(CASE `month` WHEN 'Dec' THEN revenue END) Dec_Revenue
FROM Department
GROUP BY id;

易错点

  • CASE 里写 ELSE 0,没有数据的月份会显示 0 而不是 NULL,和题目要求不同。
  • month 在部分数据库是关键字,记得加引号。
刷题进度保存在当前浏览器