前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SQL 行转列

SQL 行转列

作者头像
白日梦想家
发布2020-07-17 14:13:42
9420
发布2020-07-17 14:13:42
举报
文章被收录于专栏:SQL实现

如果你想熟练写各种统计报表的 SQL,那么行转列是你绕不开的一个点,你必须得掌握它。

行转列嘛,就是在原来的数据集上减少行数,增加列的数量。具体是什么情况,大家请往下看。

这里有一张学生成绩表,注意看,小老王 2020 年的成绩缺失了。

代码语言:javascript
复制
name              grade  point   
---------------  ------  --------
小老王                2019  3.6     
小老王                2018  4.3     
玛丽莲·梦露           2018  3.9     
玛丽莲·梦露           2019  4.2     
玛丽莲·梦露           2020  4.4     
蒜你牛                2020  4.6     
蒜你牛                2018  4.0     
蒜你牛                2019  4.3      

直接看表的数据不能很直观地了解在某个学年里每个学生的成绩,我们希望把每个学年拎出来作为列,就像下面这样子。

代码语言:javascript
复制
name             2018    2019    2020    
---------------  ------  ------  --------
小老王              4.3     3.6     (NULL)  
玛丽莲梦露          3.9     4.2     4.4     
小李子              4.0     4.3     4.6     

怎么拎出这几个列的数据呢?可以先试试用 case when 。把学年作为过滤的条件,比如过滤条件是 2018 的时候,只有属于该年度的成绩才能放到 2018 的列中。

代码语言:javascript
复制
SELECT
  NAME,
  CASE
    WHEN grade = 2018
    THEN POINT
  END AS '2018',
  CASE
    WHEN grade = 2019
    THEN POINT
  END AS '2019',
  CASE
    WHEN grade = 2020
    THEN POINT
  END AS '2020'
FROM
  t

上面的 SQL 执行之后的结果如下:

代码语言:javascript
复制
name             2018    2019    2020    
---------------  ------  ------  --------
小老王              (NULL)  3.6     (NULL)  
小老王              4.3     (NULL)  (NULL)  
玛丽莲梦露          3.9     (NULL)  (NULL)  
玛丽莲梦露          (NULL)  4.2     (NULL)  
玛丽莲梦露          (NULL)  (NULL)  4.4     
小李子              (NULL)  (NULL)  4.6     
小李子              4.0     (NULL)  (NULL)  
小李子              (NULL)  4.3     (NULL)  

这个结果和我们想要的结果有点接近了,只是每个学生还出现在多行数据中,每个学生应该只对应一行数据才合理。

把多行的数据聚合成一行可以使用聚合函数,max()min()sum() 在这里都可以使用。因为我们要看到的是每个学生的成绩,所以要将 name 字段作为分组字段。完整的 SQL 如下:

代码语言:javascript
复制
SELECT
  NAME,
  MAX(
    CASE
      WHEN grade = 2018
      THEN POINT
    END) AS '2018',
  MAX(
    CASE
      WHEN grade = 2019
      THEN POINT
    END) AS '2019',
  MAX(
    CASE
      WHEN grade = 2020
      THEN POINT
    END) AS '2020'
FROM
  t
GROUP BY NAME

写行转列(不包括动态行转列)不难,关键得知道分析哪些字段要作为分组的依据,哪个字段将拆分成多个列。然后,套上下面这个模板就可以实现功能了。

代码语言:javascript
复制
SELECT 
  分组字段1,
  分组字段2,
  [ 分组字段n ],
  MAX(
    CASE
      WHEN 条件1成立 
      THEN 数值对应的字段 
    END) AS '条件1的列名',
  MAX(
    CASE
      WHEN 条件2成立 
      THEN 数值对应的字段 
    END) AS '条件2的列名',
  MAX(条件判断n) AS '条件n的列名' 
FROM
  表 
GROUP BY 分组字段1,
  分组字段2,
  [ 分组字段n ]
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SQL实现 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
腾讯云 BI
腾讯云 BI(Business Intelligence,BI)提供从数据源接入、数据建模到数据可视化分析全流程的BI能力,帮助经营者快速获取决策数据依据。系统采用敏捷自助式设计,使用者仅需通过简单拖拽即可完成原本复杂的报表开发过程,并支持报表的分享、推送等企业协作场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档