SQL实战:01之行转列实现

文章目录

概述

我们在工作中遇到的很多场景需要将数据表中的一行的值转为一列的值,为实现这种场景可以通过IF函数或者CASE WHEN的方式来实现。恰好本人最近在刷题,就以碰到的LeetCode中的题 为例子来讲解如何使用IF和 CASE WHEN 实现行转列。

语法

IF的使用语法

IF是一个函数,有三个参数,第一个参数是判断条件,第二个参数是条件成立时的取值,第三个参数是条件不成立时的取值。

SQL 复制代码
IF(条件, 值1, 值2 )

除此以外,IF还可以嵌套使用,在一些复杂的多分支场景中就可以通过嵌套的方式来实现。

SQL 复制代码
IF(条件, 值1, IF( 条件, 值1, 值2 ) )

CASE WHEN 使用语法

SQL 复制代码
CASE WHEN 条件  THEN 操作
     WHEN 条件  THEN 操作
     ......
     ELSE 操作
END

和IF一样,CASE WHEN 也可以嵌套使用,但是得注意,每个CASE WHEN都需要保持完整。

SQL 复制代码
CASE WHEN 条件  THEN 操作
     WHEN 条件  THEN 操作
     ......
     ELSE 
        CASE WHEN 子条件 THEN 操作
             ELSE 操作 
        END
END

行转列场景

题目:重新格式话部门表

复制代码
表 Department:

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| id            | int     |
| revenue       | int     |
| month         | varchar |
+---------------+---------+
在 SQL 中,(id, month) 是表的联合主键。
这个表格有关于每个部门每月收入的信息。
月份(month)可以取下列值 ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]。
 

重新格式化表格,使得 每个月 都有一个部门 id 列和一个收入列。

以 任意顺序 返回结果表。

结果格式如以下示例所示。

 

示例 1:

输入:
Department table:
+------+---------+-------+
| id   | revenue | month |
+------+---------+-------+
| 1    | 8000    | Jan   |
| 2    | 9000    | Jan   |
| 3    | 10000   | Feb   |
| 1    | 7000    | Feb   |
| 1    | 6000    | Mar   |
+------+---------+-------+
输出:
+------+-------------+-------------+-------------+-----+-------------+
| id   | Jan_Revenue | Feb_Revenue | Mar_Revenue | ... | Dec_Revenue |
+------+-------------+-------------+-------------+-----+-------------+
| 1    | 8000        | 7000        | 6000        | ... | null        |
| 2    | 9000        | null        | null        | ... | null        |
| 3    | null        | 10000       | null        | ... | null        |
+------+-------------+-------------+-------------+-----+-------------+
解释:四月到十二月的收入为空。 
请注意,结果表共有 13 列(1 列用于部门 ID,其余 12 列用于各个月份)。

题解

  • 使用IF函数实现
sql 复制代码
select id
    ,SUM(IF(month='Jan',revenue,NULL)) AS Jan_Revenue
    ,SUM(IF(month='Feb',revenue,NULL)) AS Feb_Revenue
    ,SUM(IF(month='Mar',revenue,NULL)) AS Mar_Revenue
    ,SUM(IF(month='Apr',revenue,NULL)) AS Apr_Revenue
    ,SUM(IF(month='May',revenue,NULL)) AS May_Revenue
    ,SUM(IF(month='Jun',revenue,NULL)) AS Jun_Revenue
    ,SUM(IF(month='Jul',revenue,NULL)) AS Jul_Revenue
    ,SUM(IF(month='Aug',revenue,NULL)) AS Aug_Revenue
    ,SUM(IF(month='Sep',revenue,NULL)) AS Sep_Revenue
    ,SUM(IF(month='Oct',revenue,NULL)) AS Oct_Revenue
    ,SUM(IF(month='Nov',revenue,NULL)) AS Nov_Revenue
    ,SUM(IF(month='Dec',revenue,NULL)) AS Dec_Revenue
from Department
group by id;
  • 使用CASE WHEN实现
sql 复制代码
select id
    ,SUM(CASE WHEN month='Jan' THEN revenue ELSE NULL END) AS Jan_Revenue
    ,SUM(CASE WHEN month='Feb' THEN revenue ELSE NULL END) AS Feb_Revenue
    ,SUM(CASE WHEN month='Mar' THEN revenue ELSE NULL END) AS Mar_Revenue
    ,SUM(CASE WHEN month='Apr' THEN revenue ELSE NULL END) AS Apr_Revenue
    ,SUM(CASE WHEN month='May' THEN revenue ELSE NULL END) AS May_Revenue
    ,SUM(CASE WHEN month='Jun' THEN revenue ELSE NULL END) AS Jun_Revenue
    ,SUM(CASE WHEN month='Jul' THEN revenue ELSE NULL END) AS Jul_Revenue
    ,SUM(CASE WHEN month='Aug' THEN revenue ELSE NULL END) AS Aug_Revenue
    ,SUM(CASE WHEN month='Sep' THEN revenue ELSE NULL END) AS Sep_Revenue
    ,SUM(CASE WHEN month='Oct' THEN revenue ELSE NULL END) AS Oct_Revenue
    ,SUM(CASE WHEN month='Nov' THEN revenue ELSE NULL END) AS Nov_Revenue
    ,SUM(CASE WHEN month='Dec' THEN revenue ELSE NULL END) AS Dec_Revenue
from Department
group by id;

由以上两种实现方式可以看出,IF 比 CASE WHEN的实现方式看起来更加简洁,所以如果可以使用IF函数来实现的,都可以采用IF函数来实现,避免代码的臃肿。

相关推荐
数据知道44 分钟前
PostgreSQL 故障排查:如何找出数据库中最耗时的 SQL 语句
数据库·sql·postgresql
qq_12498707531 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
枷锁—sha1 小时前
【SRC】SQL注入WAF 绕过应对策略(二)
网络·数据库·python·sql·安全·网络安全
Coder_Boy_1 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
Gain_chance1 小时前
35-学习笔记尚硅谷数仓搭建-DWS层最近n日汇总表及历史至今汇总表建表语句
数据库·数据仓库·hive·笔记·学习
此生只爱蛋1 小时前
【Redis】主从复制
数据库·redis
马猴烧酒.2 小时前
【面试八股|JAVA多线程】JAVA多线程常考面试题详解
java·服务器·数据库
天天爱吃肉82182 小时前
跟着创意天才周杰伦学新能源汽车研发测试!3年从工程师到领域专家的成长秘籍!
数据库·python·算法·分类·汽车
大巨头2 小时前
sql2008 数据库分页语句
数据库
m0_715575342 小时前
使用PyTorch构建你的第一个神经网络
jvm·数据库·python