GROUP BY中的WITH CUBE、WITH ROLLUP原理测试及GROUPING应用[通俗易懂]

GROUP BY中的WITH CUBE、WITH ROLLUP原理测试及GROUPING应用[通俗易懂]前几天,看到一个群友用WITH ROLLUP运算符。由于自个儿没用过,看到概念及结果都云里雾里的,所以突然来了兴趣对生成结果测了一番。 一、概念: WITH CUBE:生成的结果集显示了所选列中值的所

    前几天,看到一个群友用WITH ROLLUP运算符。由于自个儿没用过,看到概念及结果都云里雾里的,所以突然来了兴趣对生成结果测了一番。

    一、概念:

    WITH CUBE:生成的结果集显示了所选列中值的所有组合的聚合。

    WITH ROLLUP:生成的结果集显示了所选列中值的某一层次结构的聚合。

    GROUPING:当行由 WITH CUBE或WITH ROLLUP运算符添加时,该函数将导致附加列的输出值为 1;当行不由 CUBE 或 ROLLUP 运算符添加时,该函数将导致附加列的输出值为 0。仅在与包含 CUBE 或 ROLLUP 运算符的 GROUP BY 子句相关联的选择列表中才允许分组。

    二、测试:

    1、建立临时表

CREATE TABLE #T0
(
    [GRADE] [VARCHAR](50) NULL,     --年级
    [CLASS] [VARCHAR](50) NULL,     --班级
    [NAME] [VARCHAR](50) NULL,      --姓名
    [COURSE] [VARCHAR](50) NULL,    --学科
    [RESULT] [NUMERIC](8,2) NULL    --成绩
)

CREATE TABLE #T1
(
    [ID] [INT] IDENTITY(1,1) NOT NULL,    --序号
    [GRADE] [VARCHAR](50) NULL,           --年级
    [CLASS] [VARCHAR](50) NULL,           --班级
    [NAME] [VARCHAR](50) NULL,            --姓名
    [COURSE] [VARCHAR](50) NULL,          --学科
    [RESULT] [NUMERIC](8,2) NULL          --成绩
)

CREATE TABLE #T2
(
    [ID] [INT] IDENTITY(1,1) NOT NULL,    --序号
    [GRADE] [VARCHAR](50) NULL,           --年级
    [CLASS] [VARCHAR](50) NULL,           --班级
    [NAME] [VARCHAR](50) NULL,            --姓名
    [COURSE] [VARCHAR](50) NULL,          --学科
    [RESULT] [NUMERIC](8,2) NULL          --成绩
)

代码100分

     2、插入测试数据

代码100分INSERT INTO #T0 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT "2019","CLASS1","9A01","C#",100
UNION
SELECT "2019","CLASS1","9A02","C#",100
UNION
SELECT "2019","CLASS2","9B01","C#",100
UNION
SELECT "2019","CLASS2","9B02","C#",100
UNION
SELECT "2018","CLASS1","8A01","JAVA",100
UNION
SELECT "2018","CLASS1","8A02","JAVA",100
UNION
SELECT "2018","CLASS2","8B01","JAVA",100
UNION
SELECT "2018","CLASS2","8B02","JAVA",100

    查询T0表结果:

GROUP BY中的WITH CUBE、WITH ROLLUP原理测试及GROUPING应用[通俗易懂]

    3、GROUP BY

    抛砖引玉,看看常用的GROUP BY排序:默认以SELECT字段顺序(GRADE->CLASS->NAME->COURSE)进行排序,以下两种查询结果是一样的。

SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT
FROM #T0
GROUP BY GRADE,CLASS,NAME,COURSE

SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT
FROM #T0
GROUP BY GRADE,CLASS,NAME,COURSE
ORDER BY GRADE,CLASS,NAME,COURSE

GROUP BY中的WITH CUBE、WITH ROLLUP原理测试及GROUPING应用[通俗易懂]

    4、WITH CUBE

    原理1:以GROUP BY字段依次赋以NULL值进行分组聚合。

    原理2:第1个字段(即GRADE字段)生成结果:除原始数据外,以第1个字段固定赋以NULL值,然后其它字段依次赋以NULL值进行分组聚合,结果由右往左进行排序

    下面开始测第1个字段的结果是怎么来的:

代码100分INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT 
FROM #T0 
GROUP BY GRADE,CLASS,NAME,COURSE

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT "ZZ" GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT 
FROM #T0 
GROUP BY CLASS,NAME,COURSE

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT "ZZ" GRADE,"ZZ" CLASS,NAME,COURSE,SUM(RESULT) RESULT 
FROM #T0 
GROUP BY NAME,COURSE

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT "ZZ" GRADE,"ZZ" CLASS,"ZZ" NAME,COURSE,SUM(RESULT) RESULT 
FROM #T0 
GROUP BY COURSE

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT "ZZ" GRADE,"ZZ" CLASS,"ZZ" NAME,"ZZ" COURSE,SUM(RESULT) RESULT 
FROM #T0

--第1个字段结果排序由右往左
INSERT INTO #T2 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,CLASS,NAME,COURSE,RESULT FROM #T1 WHERE ID BETWEEN 1 AND 27 ORDER BY COURSE,NAME,CLASS,GRADE

UPDATE #T2 SET GRADE=NULL WHERE GRADE="ZZ"
UPDATE #T2 SET CLASS=NULL WHERE CLASS="ZZ"
UPDATE #T2 SET NAME=NULL WHERE NAME="ZZ"
UPDATE #T2 SET COURSE=NULL WHERE COURSE="ZZ"

    WITH CUBE的结果:

SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT
FROM #T0
GROUP BY GRADE,CLASS,NAME,COURSE
WITH CUBE

GROUP BY中的WITH CUBE、WITH ROLLUP原理测试及GROUPING应用[通俗易懂]

    自已测试的结果:

SELECT * FROM #T2

GROUP BY中的WITH CUBE、WITH ROLLUP原理测试及GROUPING应用[通俗易懂]

    结果与上面一致。

    其它字段优先跟哪个字段组合、最终怎样排序?呃,测过,没搞清楚……

    5、WITH ROLLUP

    原理1:除原始数据外,以GROUP BY最后1个字段(即COURSE字段)固定赋以NULL值,然后其它字段依次赋以NULL值进行分组聚合,结果由左往右进行排序

    这个跟WITH CUBE的第1个字段非常相象:一个是第1个字段,一个是最后1个字段;一个结果是由右往左排序,一个结果是由左往右排序。

    下面开始测结果是怎么来的:

TRUNCATE TABLE #T1
TRUNCATE TABLE #T2

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT 
FROM #T0 
GROUP BY GRADE,CLASS,NAME,COURSE

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,CLASS,NAME,"ZZ" COURSE,SUM(RESULT) RESULT 
FROM #T0 
WHERE NOT EXISTS (SELECT 1 FROM #T1 WHERE GRADE=#T0.GRADE AND CLASS=#T0.GRADE AND NAME=#T0.NAME AND COURSE="ZZ")
GROUP BY GRADE,CLASS,NAME

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,CLASS,"ZZ" NAME,"ZZ" COURSE,SUM(RESULT) RESULT 
FROM #T0 
WHERE NOT EXISTS (SELECT 1 FROM #T1 WHERE GRADE=#T0.GRADE AND CLASS=#T0.CLASS AND NAME="ZZ" AND COURSE="ZZ")
GROUP BY GRADE,CLASS

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,"ZZ" CLASS,"ZZ" NAME,"ZZ" COURSE,SUM(RESULT) RESULT 
FROM #T0 
WHERE NOT EXISTS (SELECT 1 FROM #T1 WHERE GRADE=#T0.GRADE AND CLASS="ZZ" AND NAME="ZZ" AND COURSE="ZZ")
GROUP BY GRADE

INSERT INTO #T1 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT "ZZ" GRADE,"ZZ" CLASS,"ZZ" NAME,"ZZ" COURSE,SUM(RESULT) RESULT 
FROM #T0 

--结果排序由左往右
INSERT INTO #T2 (GRADE,CLASS,NAME,COURSE,RESULT)
SELECT GRADE,CLASS,NAME,COURSE,RESULT FROM #T1 ORDER BY GRADE,CLASS,NAME,COURSE

UPDATE #T2 SET GRADE=NULL WHERE GRADE="ZZ"
UPDATE #T2 SET CLASS=NULL WHERE CLASS="ZZ"
UPDATE #T2 SET NAME=NULL WHERE NAME="ZZ"
UPDATE #T2 SET COURSE=NULL WHERE COURSE="ZZ"

    WITH ROLLUP的结果:

SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT
FROM #T0
GROUP BY GRADE,CLASS,NAME,COURSE
WITH ROLLUP

GROUP BY中的WITH CUBE、WITH ROLLUP原理测试及GROUPING应用[通俗易懂]

    自己测试的结果:

SELECT * FROM #T2

GROUP BY中的WITH CUBE、WITH ROLLUP原理测试及GROUPING应用[通俗易懂]

    结果与上面一致。

    6、GROUPING

    这个就比较容易理解了,WITH CUBE与WITH ROLLUP用法一样,先看结果:

SELECT GRADE,CLASS,NAME,COURSE,SUM(RESULT) RESULT,GROUPING(COURSE) [GROUPING]
FROM #T0
GROUP BY GRADE,CLASS,NAME,COURSE
WITH ROLLUP

GROUP BY中的WITH CUBE、WITH ROLLUP原理测试及GROUPING应用[通俗易懂]

    上面GROUPING的是COURSE字段,有NULL值就是WITH ROLLUP额外添加的,GROUPING结果值为1。

    有了GROUPING,那做小计、总计就方便了。

SELECT 
    GRADE,
    CASE WHEN GROUPING(GRADE)=1 AND GROUPING(CLASS)=1 THEN "总计" WHEN GROUPING(GRADE)=0 AND GROUPING(CLASS)=1 THEN "小计" ELSE CLASS END CLASS,
    NAME,COURSE,SUM(RESULT) RESULT
FROM #T0
GROUP BY GRADE,CLASS,NAME,COURSE
WITH ROLLUP

GROUP BY中的WITH CUBE、WITH ROLLUP原理测试及GROUPING应用[通俗易懂]

     好了,原理测试及应用就到这里结束了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/11121.html

(0)
上一篇 2022-12-16
下一篇 2022-12-16

相关推荐

  • Excel数据分析入门-函数和公式[亲测有效]

    Excel数据分析入门-函数和公式[亲测有效]I. 使用公式 II. 常用Excel函数 III. 统计分析函数实战 IV. 其他部分实用函数索引 DATEDIF 函数 : 计算两个日期之间的天数、月数或年数。 此函数在用于计算年龄的公式中很有用。 IFS 函数: 检查是否满足一个或多个条件,且是否返回与第一个 TRUE …

    2023-03-02
    82
  • MySQL8.0关系数据库基础教程(三)-select语句详解[通俗易懂]

    MySQL8.0关系数据库基础教程(三)-select语句详解[通俗易懂]1 查询指定字段 在 employee 表找出所有员工的姓名、性别和电子邮箱。 SELECT 表示查询,随后列出需要返回的字段,字段间逗号分隔 FROM 表示要从哪个表中进行查询 分号为语句结束符 这

    2023-01-29
    104
  • 外键有什么用_外键可以重复吗

    外键有什么用_外键可以重复吗这篇主要说明表属性 – 外键。 外键的设计初衷是为了在数据库端保证对逻辑上相关联的表数据在操作上的一致性与完整性。 外键在大部分企业写的开发规范里会**直接规避掉!**外键有优缺点,也并不是说每种场…

    2023-03-05
    104
  • TiKV 源码解析系列文章(十五)表达式计算框架[通俗易懂]

    TiKV 源码解析系列文章(十五)表达式计算框架[通俗易懂]作者:骆迪安 上一篇 《TiKV 源码解析系列文章(十四)Coprocessor 概览》讲到了 TiDB 为了最大化利用分布式计算能力,会尽量将 Selection 算子、聚合算子等算子下推到 Ti…

    2022-12-19
    94
  • 时序数据库 Apache-IoTDB 源码解析之系统架构(二)

    时序数据库 Apache-IoTDB 源码解析之系统架构(二)上一章聊到时序数据是什么样,物联网行业中的时序数据的特点:存量数据大、新增数据多(采集频率高、设备量多)。详情请见: 时序数据库 Apache-IoTDB 源码解析之前言(一) 这一章主要想聊一聊:…

    2023-01-26
    97
  • Python Setup.py:构建和分发Python软件的核心工具

    Python Setup.py:构建和分发Python软件的核心工具Python是一种高级编程语言,已经成为了web开发、数据科学、机器学习等领域的主要语言之一。当你开发了一个Python代码库,你希望在其他地方使用它,那么如何分发这个代码库呢?这就需要用到Python Setup.py,一个构建和分发Python软件的核心工具。本文将详细介绍Python Setup.py的使用方法。

    2023-12-06
    63
  • MySQL中的全表扫描和索引树扫描[通俗易懂]

    MySQL中的全表扫描和索引树扫描[通俗易懂]引言 在学习mysql时,我们经常会使用explain来查看sql查询的索引等优化手段的使用情况。在使用explain时,我们可以观察到,explain的输出有一个很关键的列,它就是type属性,ty

    2023-05-16
    92
  • mongo和mysql应用场景_kafka使用场景

    mongo和mysql应用场景_kafka使用场景https://www.cnblogs.com/linguoguo/p/10640179.html MongoDB: 更高的写入负载 默认情况下,MongoDB更侧重高数据写入性能,而非事务安全,Mo

    2023-02-10
    113

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注