如何在Oracle SQL中用CASE结合SUM实现行转列分组求和
Oracle SQL 行转列求和问题解决
问题背景
现有数据表包含item_id、month_in、amount三列,数据如下:
| item_id | month_in | amount |
|---|---|---|
| 1 | 1 | 1500 |
| 1 | 1 | 1000 |
| 2 | 1 | 2500 |
| 3 | 1 | 2600 |
| 3 | 1 | 1000 |
| 4 | 1 | 2700 |
| 4 | 1 | 1000 |
| 1 | 2 | 1500 |
| 1 | 2 | 2000 |
| 2 | 2 | 1000 |
| 3 | 3 | 2500 |
| 3 | 3 | 2500 |
| 4 | 3 | 1000 |
| 4 | 3 | 2500 |
需要将数据转换为按item_id分组,每个月份作为单独列展示求和结果,期望输出如下:
| item_id | januari | februari | maret |
|---|---|---|---|
| 1 | 2500 | 3500 | 0 |
| 2 | 2500 | 1000 | 0 |
| 3 | 3600 | 0 | 0 |
| 4 | 3700 | 0 | 3500 |
用户尝试的SQL语句如下,但未得到预期结果:
select item_id, (case month_in=1 then sum(amout) end) AS januari from table group by item_id, month_in order by item_id asc
问题分析
原SQL存在几个问题:
- 语法错误:
case的写法不符合规范,正确格式应为case when month_in=1 then ... - 字段拼写错误:
amout应为amount - 分组逻辑错误:按
item_id, month_in分组会导致每个item的每个月份单独成一行,无法合并为一行展示所有月份数据 - 求和逻辑错误:应先筛选对应月份的数据再求和,且未处理无数据月份的NULL值转换为0的需求
正确SQL语句
SELECT item_id, NVL(SUM(CASE WHEN month_in = 1 THEN amount END), 0) AS januari, NVL(SUM(CASE WHEN month_in = 2 THEN amount END), 0) AS februari, NVL(SUM(CASE WHEN month_in = 3 THEN amount END), 0) AS maret FROM your_table_name GROUP BY item_id ORDER BY item_id ASC;
说明
- CASE嵌套SUM:先通过
CASE WHEN筛选对应月份的amount值,再用SUM对该月份的所有数据求和,确保每个item_id仅返回一行数据 - NVL处理空值:当某个item在对应月份没有数据时,SUM会返回NULL,
NVL(..., 0)将其转为0,匹配期望结果的格式 - 仅按item_id分组:保证同一item的所有月份数据合并到一行展示
内容的提问来源于stack exchange,提问作者Abdurrahman Al-Amin Buluatie
相关产品推荐
相关产品推荐

