时不时地,您会遇到一个使您达到SQL限制的要求。 我们中的许多人可能会提早放弃并使用Java / [或您的语言]计算内容。 相反,使用SQL可能是如此简单快捷。 如果您使用的是高级数据库,例如DB2 , Oracle , SQL Server , Sybase SQL Anywhere (以及本例中的MySQL ,它们支持WITH ROLLUP子句),则可以利用ROLLUP / CUBE / GROUPING SETS分组功能。

让我们看一下我的虚构薪水与虚构的朋友相比,后者选择了不同的职业道路(观察2011年的薪水增长情况):

select 'Lukas'      as employee, 'SoftSkills' as company, 80000        as salary, 2007         as year from dualunion all select 'Lukas', 'SoftSkills', 80000,  2008 from dualunion all select 'Lukas', 'SmartSoft',  90000,  2009 from dualunion all select 'Lukas', 'SmartSoft',  95000,  2010 from dualunion all select 'Lukas', 'jOOQ',       200000, 2011 from dualunion all select 'Lukas', 'jOOQ',       250000, 2012 from dualunion all select 'Tom',   'SoftSkills', 89000,  2007 from dualunion all select 'Tom',   'SoftSkills', 90000,  2008 from dualunion all select 'Tom',   'SoftSkills', 91000,  2009 from dualunion all select 'Tom',   'SmartSoft',  92000,  2010 from dualunion all select 'Tom',   'SmartSoft',  93000,  2011 from dualunion all select 'Tom',   'SmartSoft',  94000,  2012 from dual

现在,我们习惯于使用简单的分组和简单的聚合函数来收集统计信息。 例如,让我们计算一下卢卡斯和汤姆在过去几年中的平均收入:

with data as ([above select])select employee, avg(salary)from datagroup by employee

这将表明Lukas赚了更多:

+--------+-----------+
|EMPLOYEE|AVG(SALARY)|
+--------+-----------+
|Lukas   |     132500|
|Tom     |      91500|
+--------+-----------+

因此,找出他们在哪家公司的平均收入可能很有趣:

with data as (...)select company, employee, avg(salary)from datagroup by company, employeeorder by company, employee

随即,很明显,大笔钱在哪里,汤姆做出了一个错误的决定。

+----------+--------+-----------+
|COMPANY   |EMPLOYEE|AVG(SALARY)|
+----------+--------+-----------+
|jOOQ      |Lukas   |     225000|
|SmartSoft |Lukas   |      92500|
|SmartSoft |Tom     |      93000|
|SoftSkills|Lukas   |      80000|
|SoftSkills|Tom     |      90000|
+----------+--------+-----------+

卷起

通过添加分组字段,我们“丢失”了一些聚合信息。 在以上示例中,不再直接从结果中获得每位员工的总体平均工资。 考虑到分组算法,这很明显。 但是在美观的报告中,我们通常也希望显示这些分组标题。 这是ROLLUP,CUBE(和GROUPING SETS)起作用的地方。 考虑以下查询:

with data as (...)select company, employee, avg(salary)from datagroup by rollup(company), employee

上面的汇总功能现在将向分组结果集中添加其他行,并保留有用的汇总值。 在这种情况下,当我们“汇总公司的薪水”时,我们将获得剩余分组字段的平均值,即每位员工的平均值:

+----------+--------+-----------+
|COMPANY   |EMPLOYEE|AVG(SALARY)|
+----------+--------+-----------+
|SmartSoft |Tom     |      93000|
|SoftSkills|Tom     |      90000|
|{null}    |Tom     |      91500|
|jOOQ      |Lukas   |     225000|
|SmartSoft |Lukas   |      92500|
|SoftSkills|Lukas   |      80000|
|{null}    |Lukas   |     132500|
+----------+--------+-----------+

请注意,这些行与第一个查询(第一个查询仅由员工分组)所保存的信息相同。当我们将更多分组字段放入汇总功能时,这将变得更加有趣:

with data as (...)select company, employee, avg(salary)from datagroup by rollup(employee, company)

如您所见,分组字段的顺序在汇总功能中很重要。 现在,此查询的结果还将添加支付给所有公司中所有员工的总体平均工资

+----------+--------+-----------+
|COMPANY   |EMPLOYEE|AVG(SALARY)|
+----------+--------+-----------+
|SmartSoft |Tom     |      93000|
|SoftSkills|Tom     |      90000|
|{null}    |Tom     |      91500|
|jOOQ      |Lukas   |     225000|
|SmartSoft |Lukas   |      92500|
|SoftSkills|Lukas   |      80000|
|{null}    |Lukas   |     132500|
|{null}    |{null}  |     112000|
+----------+--------+-----------+

为了标识要报告的总计行,可以在DB2,Oracle,SQL Server和Sybase SQL Anywhere中使用GROUPING()函数。 在Oracle和SQL Server中,还有更有用的GROUPING_ID()函数:

with data as (...)select grouping_id(employee, company) id, company, employee, avg(salary)from datagroup by rollup(employee, company)

它记录了当前行产生在汇总功能的哪个“分组级别”上:

+----+----------+--------+-----------+
|  ID|COMPANY   |EMPLOYEE|AVG(SALARY)|
+----+----------+--------+-----------+
|   0|SmartSoft |Tom     |      93000|
|   0|SoftSkills|Tom     |      90000|
|   1|{null}    |Tom     |      91500|
|   0|jOOQ      |Lukas   |     225000|
|   0|SmartSoft |Lukas   |      92500|
|   0|SoftSkills|Lukas   |      80000|
|   1|{null}    |Lukas   |     132500|
|   3|{null}    |{null}  |     112000|
+----+----------+--------+-----------+

立方体

多维数据集功能的工作原理类似,但多维数据集分组字段的顺序变得无关紧要,因为所有分组组合都已合并。 说起来有点棘手,所以让它付诸实践:

with data as (...)select grouping_id(employee, company) id, company, employee, avg(salary)from datagroup by cube(employee, company)

在以下结果中,您将获得:

  • GROUPING_ID()= 0:每个公司和每个员工的平均值。 这是正常的分组结果
  • GROUPING_ID()= 1:每位员工的平均值
  • GROUPING_ID()= 2:每个公司的平均值
  • GROUPING_ID()= 3:总体平均
+----+----------+--------+-----------+
|  ID|COMPANY   |EMPLOYEE|AVG(SALARY)|
+----+----------+--------+-----------+
|   3|{null}    |{null}  |     112000|
|   2|jOOQ      |{null}  |     225000|
|   2|SmartSoft |{null}  |      92800|
|   2|SoftSkills|{null}  |      86000|
|   1|{null}    |Tom     |      91500|
|   0|SmartSoft |Tom     |      93000|
|   0|SoftSkills|Tom     |      90000|
|   1|{null}    |Lukas   |     132500|
|   0|jOOQ      |Lukas   |     225000|
|   0|SmartSoft |Lukas   |      92500|
|   0|SoftSkills|Lukas   |      80000|
+----+----------+--------+-----------+

换句话说,使用CUBE()函数,您将获得提供给CUBE()函数的分组字段的每种可能组合的分组结果,这将为n个“立方”分组字段产生2 ^ n GROUPING_ID()

jOOQ中的支持

jOOQ 2.0引入了对这些功能的支持。 如果要将最后一个选择转换为jOOQ,则可以大致得到以下Java代码:

// assuming that DATA is an actual table...create.select(groupingId(DATA.EMPLOYEE, DATA.COMPANY).as("id"),DATA.COMPANY, DATA.EMPLOYEE, avg(SALARY)).from(DATA).groupBy(cube(DATA.EMPLOYEE, DATA.COMPANY));

有了这个功能强大的工具,您就可以准备好所有这些精美的报告和数据概述。 有关更多详细信息,请在SQL Server文档页面上继续阅读有关ROLLUP(),CUBE()和GROUPING SETS()函数的内容,其中对此进行了很好的解释:
http://msdn.microsoft.com/en-us/library/bb522495.aspx

参考:来自JAVA,SQL和JOOQ博客的JCG合作伙伴 Lukas Eder的GROUP BY ROLLUP / CUBE 。

相关文章 :

  • Java中的数据库架构导航
  • ORM问题
  • SQL或NOSQL:这是问题吗?
  • 什么是NoSQL?

翻译自: https://www.javacodegeeks.com/2011/12/group-by-rollup-cube.html

按汇总分组/多维数据集相关推荐

  1. 数据湖 多维数据集_按汇总分组/多维数据集

    数据湖 多维数据集 时不时地,您会遇到一个使您达到SQL限制的要求. 我们中的许多人可能会早早放弃并使用Java / [或您的语言]计算内容. 相反,使用SQL可能是如此简单快捷. 如果您使用的是高级 ...

  2. 微软BI 之SSAS 系列 - 多维数据集维度用法之二 事实维度(退化维度 Degenerate Dimension)...

    这篇文章是基于上一篇 SSAS 系列 - 多维数据集维度用法之一 引用维度 Referenced Dimension 继续讲解多维数据集维度用法中的事实维度. 事实维度,顾名思义就是把事实表 Fact ...

  3. olap 多维分析_如何通过依赖T-SQL从OLAP多维数据集有效地提取数据

    olap 多维分析 介绍 (Introduction) Last month I ran two Business Intelligence pre-conferences in South Afri ...

  4. SSAS系列——【03】多维数据(多维数据集对象)

    原文:SSAS系列--[03]多维数据(多维数据集对象) 1.什么是Cube? 简单 Cube 对象由基本信息.维度和度量值组组成. 基本信息包括多维数据集的名称.多维数据集的默认度量值.数据源和存储 ...

  5. sql2018 ssas_如何使用SQL Server Analysis Services(SSAS)从头开始构建多维数据集

    sql2018 ssas 介绍 (Introduction) I am a DBA consultant and several times, in the past, I have been ask ...

  6. ssas报表项目数据集_处理SSAS多维OLAP多维数据集的有效方法

    ssas报表项目数据集 介绍 (Introduction) While building and deploying an SSAS OLAP cube, there are two processi ...

  7. ssas报表项目数据集_Analysis Services(SSAS)多维设计技巧–数据源视图和多维数据集

    ssas报表项目数据集 In this article, we'll discuss some tips and best practices regarding the design of OLAP ...

  8. 《BI项目笔记》用Excel2013连接和浏览OLAP多维数据集

    <BI项目笔记>用Excel2013连接和浏览OLAP多维数据集 原文:<BI项目笔记>用Excel2013连接和浏览OLAP多维数据集 用Excel2013连接和浏览OLAP ...

  9. 【camera】自动泊车-视觉车位检测相关资料汇总(论文、数据集、源代码、相关博客、演示demo)(1)

    [camera]自动泊车-视觉车位检测相关资料汇总(论文.数据集.源代码.相关博客.演示demo)parking slot detection 论文 2020论文 2019论文 2018论文 2017 ...

最新文章

  1. linux单次任务调度,go任务调度2(linux的cron调用)
  2. 为Ubuntu Server 安装图形桌面环境
  3. Unity对接Steam SDK
  4. 20.大型网站典型故障分析
  5. php汉字组合算法,php数字转汉字的函数算法
  6. Apache Flink 1.7.2 发布,流处理框架
  7. StuQ IT技能图谱全集
  8. c语言在线翻译器,command(c语言翻译工具)
  9. 基于asp.net的电影院订票售票管理系统
  10. 什么是php-fpm
  11. java构造扑克牌算法_java扑克牌算法
  12. linux - glib使用
  13. [经典面试题]实现memcpy库函数
  14. SSH远程登录与控制
  15. DSP28335入门教程:寄存器手册的下载
  16. 实现QQ表情功能(1)
  17. 2016码农谷全国大学生程序设计邀请赛(测试赛)
  18. Proxy代理简单使用
  19. 魔兽的服务器和客户机python_怎么自己架设wow私服服务器
  20. Vs2017+opencv调用大恒图像相机,实现读存操作

热门文章

  1. jvm(1)-走进java
  2. php cdi_通过MicroProfile上下文传播增强了CDI上下文和隔板
  3. java策略设计模式_Java中的策略设计模式
  4. ubuntu安装jdk语句_JDK 12:实际中的切换语句/表达式
  5. Java 9:Process API的增强
  6. spring可用于数据层吗_Spring XD用于数据提取
  7. java 登陆验证失败_使用Java 8流进行快速失败的验证
  8. AWS Lambda将数据保存在DynamoDB中
  9. javafx 自定义控件_JavaFX自定义控件– Nest Thermostat第2部分
  10. junit动态忽略测试_有条件忽略测试的JUnit规则