总第151篇/张俊红

这一篇讲讲 group by plus,大家应该都知道 group by,可是 plus 是什么鬼呢?其实和 iphone plus一样,就是升级版的意思。那到底这个 plus 是个什么东西呢?我们接下来慢慢讲。

01|前言

我们先来看个数据需求场景,现在我有一张明细表,这张表里面存储了每个店铺的成交明细,其中包含每个店铺所属的城市、地区、大区属性,我需要通过这张明细表获取到每个店铺、每个城市、每个省份、每个大区以及全国在最近一个月的成交量情况,我该怎么做呢?

明细表 t 如下:

有一种最简单的方法就是,我们写5个 Sql 语句,然后将数据导出来在 Excel 中处理。5个 Sql 语句如下:想一下,我们要做上面的那个需求,我们应该怎么做呢?

全国成交量
select count(orderid) as sales from t where deal_date between "2019-05-01" and "2019-05-31"
大区成交量
select area,count(orderid) as sales
from t
where deal_date between "2019-05-01" and "2019-05-31"
group by area
省份成交量
select area,province,count(orderid) as sales
from t
where deal_date between "2019-05-01" and "2019-05-31"
group by area,province
城市成交量
selectarea,province ,city,count(orderid) as sales
from t
where deal_date between "2019-05-01" and "2019-05-31"
group by area,province ,city
店铺成交量
select area,province ,city,shop,count(orderid) as sales
from t
where deal_date between "2019-05-01" and "2019-05-31"
group by area,province ,city,shop

上面这种方法可以达到我们的目的,满足我们的需求,但是这种方法太低效了,我们在Excel中还需要做合并处理,很麻烦。能不能把上面几种结果在 Sql 中就进行合并处理,这样就不需要在 Excel 中合并了。答案是可以的,需要借助的就是 unionunion all,对查询结果进行纵向合并。

union 和 union all的区别在于:前者是对合并后的结果进行去重处理,而后者返回合并后的所有数据。

具体代码如下:

select null,null,null,null,count(orderid) as sales from t where deal_date between "2019-05-01" and "2019-05-31"union allselect area,null,null,null,count(orderid) as sales from t where deal_date between "2019-05-01" and "2019-05-31"group by areaunion allselect area,province,null,null,count(orderid) as sales from t where deal_date between "2019-05-01" and "2019-05-31"group by area,provinceunion allselect area,province ,city,null,count(orderid) as sales from t where deal_date between "2019-05-01" and "2019-05-31"group by area,province,cityunion allselect area,province,city,shop,count(orderid) as sales  from t where deal_date between "2019-05-01" and "2019-05-31"group by area,province ,city,shop

大家应该注意到上面的语句中 select 了很多 null,那是因为 union all 拼接的两个表的列数需要相等。最后出来的结果如下:

02|grouping sets

利用 union all 要比导出5个Sql然后再在 Excel 中处理简单多了,但是有没有发现上面的代码很长,很冗余。有人发现了,有人不仅发现了,还想出了一种更好的方法去解决,具体是什么方法呢?就是我们今天要讲的group byplus 版。真名叫做 grouping sets。这个 plus 可以根据不同维度组合进行聚合。比如根据大区聚合、根据大区和省份聚合、根据大区省份和城市聚合、根据大区省份城市和店铺聚合。

将上面 union all 语句用 grouping sets 改写以后,代码如下:

select null,area,province,city,shop,count(orderid) as sales,grouping_id
from t
where deal_date between "2019-05-01" and "2019-05-31"
group by null,area,province,city,shop
grouping sets(null,area,(area,province),(area,province,city),(area,province ,city,shop))
order by grouping_id

上面代码得到的效果和利用 union all 拼接得到的效果是一样的,但是要比拼接的代码简洁很多。group by后面放的字段表示要分组聚合的全部字段,grouping sets 后面放的是 group by 后面各种字段的组合,根据实际需求进行组合就行,组合字段用小括号括起来,也可以是单一字段。

在求取全国的成交量的时候其实是不需要分组聚合的,但是为了使用 grouping sets,所以我们在求取全国成交量的时候用 group by null

grouping_id 用来表示每个分组的序号。1表示第一个分组、2表示第二个分组、。。。我们可以根据grouping_id 选取出我们需要的组合。如果我们需要全国的成交量,让 grouping_id = 1 即可;如果我们需要每个省份的成交量,让 grouping_id = 3 即可。其他也是同样的道理。

03|cube

看完 grouping sets 后,我们再来看另一个 plus 版,就是 cube。这个函数是对 group by 的维度的所有组合进行聚合。直接来看代码:

select area,province,count(orderid) as sales,grouping_id
from t
where deal_date between "2019-05-01" and "2019-05-31"
group by area,province
with cube
order by grouping_id

上面代码是对区域和省份进行聚合,并利用了 cube ,最后得到的结果如下:

cube 会先对全部数据进行聚合,即 null,null,再对 area,null 进行聚合,然后再对 null,province 进行聚合,最后再对 area,province进行聚合。

04|rollup

再来看一下最后一个 plus 版,就是 rollup。这个函数其实和 cube 挺像的,是针对 group by 所有维度的部分组合。还是上面的例子,我们来看一下运行结果。代码如下:

select area,province,count(orderid) as sales,grouping_id
from t
where deal_date between "2019-05-01" and "2019-05-31"
group by area,province
with rollup
order by grouping_id

最后得到的结果如下:

仔细观察一下 cuberollup 得到的结果,我们会发现 rollup 少了 null province 这一个组合,看出差别来了吧,rollup 是以最左侧指标为主进行组合聚合。

这一节讲的这几个 plus 版函数很实用,如果熟练掌握了,可以减少很多工作量的。

你还可以看:

Sql 的执行顺序是怎样的?

Sql 实现数据透视表功能

讲讲你不知道的窗口函数

讲讲 group by 的plus版相关推荐

  1. 讲讲 group by 的实现原理

    总第168篇/张俊红 写过 Sql 的同学应该都知道 group by 是用来对数据进行分组的,一般与聚合函数一起使用,对分组后的数据进行聚合.虽然大家都在用,但是有些同学还是不太清楚 group b ...

  2. 关于 Group 的另一个函数

    总第155篇/张俊红 今天给大家分享一下关于 Group 的另一个函数 Group_Concat. 先给大家科普两个概念,宽表和窄表. 宽表是将多个维度的信息放在一个表中,组成一个很宽很宽的表.比如订 ...

  3. 你知道 Sql 中 left join 的底层原理吗?

    总第165篇/张俊红 01.前言 写过或者学过 Sql 的人应该都知道 left join,知道 left join 的实现的效果,就是保留左表的全部信息,然后把右表往左表上拼接,如果拼不上就是 nu ...

  4. Sql 中的变量使用

    总第162篇/张俊红 我们在学 Python 或者其他编程语言的时候都应该有学过变量这么一个东西,可是 Sql 这种查询语言中怎么也有变量呢?具体有什么用呢? 我们来看一下实际应用场景. 现在有这么一 ...

  5. 介绍一下 information_schema 库

    总第152篇/张俊红 今天给大家介绍一款 Mysql 中附属的数据库,就是 information_schema 数据库,为什么说是附属呢?是因为这个数据库是在安装 Mysql 的同时就会安装到你电脑 ...

  6. 介绍一位零基础转行数据分析的好友

    今天给大家介绍一位我的好友:张俊红,他的公众号也叫张俊红. 俊红大学学的专业是毕业以后是去煤矿做一名矿工,他靠着自学成功从一名『矿工』转行成为了一名数据分析师,不仅转行成功了.还写了一本畅销书『对比E ...

  7. group by 的实现原理

    转载:https://cloud.tencent.com/developer/article/1513067 写过 Sql 的同学应该都知道 group by 是用来对数据进行分组的,一般与聚合函数一 ...

  8. 网易云音乐电脑版怎么下载电台节目 主播电台节目下载教程

    网易云音乐不仅可以听歌,还可以在主播电台中,听到各类主播的声音,下面我们就来讲讲网易云音乐电脑版怎么下载电台节目,一起来看教程吧! 网易云音乐电脑版怎么下载电台节目 主播电台节目下载教程 网易云音乐P ...

  9. WEB开发文档2 总结

    转自:http://blog.donews.com/lvjiyong/archive/2006/06/29/931071.aspx 怎样将后台生成的在内存中的图象显示到客户端 Microsoft IE ...

最新文章

  1. nUnit,凑合着测试
  2. linux磁盘阵列oravote,Oracle在Linux下集群RAC的安装与启停
  3. 小工具发布,QCountDown-语音倒计时
  4. Java EE 6示例– Galleria
  5. VUE.JS 组件化开发实践
  6. poj2376 区间贪心 挑战程序设计竞赛
  7. 网页聊天室win10界面源码
  8. 大数据学习笔记14:MR案例——招聘数据分析
  9. JS (与运算)详解
  10. Power BI数据可视化
  11. clappr.js:Web开源媒体播放器,可扩展网页媒体播放器
  12. react报错:Uncaught Error: Element type is invalid: expected a string (for built-in components) or a ..
  13. EOS区块链技术开发(二)智能合约
  14. python创建多个文件夹合并_在python中如何将多个文件夹合并到一个文件夹中?
  15. 基于深度学习的语音分类识别(附代码)
  16. 聚类dbi指数_聚类-K-Means
  17. linux系统下查看服务器品牌型号序列号
  18. 华为怎么设置计算机快捷,使用命令快速设置华为路由器
  19. BIM设计要做哪些准备工作才能真正完成建筑全生命周期的使命
  20. pikachu通关教程~~~~

热门文章

  1. Mybatis报错: Invalid bound statement (not found)...
  2. sql 查出一张表中重复的所有记录数据
  3. HTTPClient 出现Cannot inherit from final class
  4. ConstraintLayout如何优化布局性能
  5. Android Camera 流程学习记录(五)—— Camera.takePicture() 流程解析
  6. nginx利用image_filter动态生成缩略图
  7. 剑指offer之链表续
  8. 【python】【scrapy】使用方法概要(三)
  9. 到国外使用wifi悠着点防止天价帐单
  10. I am beginning perl