当前位置: 首页 > news >正文

SQL实战:01之行转列实现

文章目录

  • 概述
  • 语法
    • IF的使用语法
    • CASE WHEN 使用语法
  • 行转列场景
    • 题目:重新格式话部门表
    • 题解

概述

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

语法

IF的使用语法

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

IF(条件, 值1, 值2 )

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

IF(条件, 值1, IF( 条件, 值1, 值2 ) )

CASE WHEN 使用语法

CASE WHEN 条件  THEN 操作WHEN 条件  THEN 操作……ELSE 操作
END

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

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函数实现
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实现
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函数来实现,避免代码的臃肿。

相关文章:

  • 在线地图工具geojson.io
  • Godot开发2D冒险游戏——第一节:主角登场!
  • 4.1.1 类的序列化与反序列化(XmlSerializer)
  • [原创](现代Delphi 12指南):[macOS 64bit App开发]:如何使用NSString类型字符串?
  • Tomcat Web应用(Ubuntu 18.04.6 LTS)部署笔记
  • React-组件通信
  • 【高中数学/古典概率】4红2黑六选二,求取出两次都是红球的概率
  • AI在论文评审中的应用与工具推荐
  • WASM与Kotlin反编译难度对比分析
  • NVIDIA自动驾驶安全与技术读后感
  • 【低配置电脑预训练minimind的实践】
  • 关于 xpath 查找 XML 元素的一点总结
  • go.mod介绍
  • ‌RISC-V低功耗MCU动态时钟门控技术详解
  • CSS基础
  • 第二章、安全认证
  • Nginx 二进制部署与 Docker 部署深度对比
  • 学习海康VisionMaster之顶点检测
  • 03_JavaScript
  • 云网络与SASE架构:构建下一代企业安全网络
  • 长三角与粤港澳大湾区融合发展,无锡何以成为窗口?
  • 法治日报:强制统一店铺广告牌匾事件何以频发?
  • 央媒关注脑瘫女骑手:7年跑出7.3万多份单,努力撑起生活
  • 金地集团:保交楼为经营的首要任务,将根据融资性现金流恢复程度等进行投资决策
  • 王毅同英国外交大臣拉米通电话
  • 中国全国政协-越南祖国阵线中央暨边境省份组织第三次友好交流活动在南宁开幕