MYSQL——解决多维度随机组合查询场景:grouping sets函数

2023-10-27

一、引入

        注意:通常用在构建数据集市和复杂随机组合场景查询时使用

        对于经常需要对数据进行多维度的聚合分析的场景,您既需要对A列做聚合,也要对B列做聚合,同时要对A、B两列做聚合,因此需要多次使用union all

        案例:        

        比如此处有一张表temp:

        temp表字段:城市、渠道、订单类型、销售额;

        temp表数据:

城市 渠道 订单类型 订单金额
北京 淘宝 家具 1600
上海 淘宝 家具 900
北京 淘宝 数码 1800
上海 淘宝 数码 700
北京 京东 数码 800
上海 京东 数码 1600
北京 京东 家具 1000
上海 京东 家具 800

        业务需求:求渠道和订单类型两个维度随机组合下的订单总金额

        通常的解决方案,我们是先按渠道和订单类型做聚合求订单总金额,再按订单类型维度做聚合求订单总金额,再按渠道类型维度做聚合求订单总金额,之后求渠道和订单类型下的订单总金额,最后四个结果union在一起:

        代码:

select 渠道, '全部订单类型' 订单类型,sum(订单金额)
from temp
group by 渠道

union all

select '全部渠道' 渠道,订单类型,sum(订单金额)
from temp
group by 订单类型

union all

select 渠道,订单类型,sum(订单金额)
from temp
group by 渠道,订单类型

union all

select '全部渠道' 渠道,'全部订单类型' 订单类型,sum(订单金额)
from temp
;

        结果:

渠道 订单类型 订单总金额
全部渠道 数码 4900
全部渠道 家具 4300
全部渠道 全部订单类型 9200
京东 全部订单类型 4200
淘宝 全部订单类型 5000
京东 数码 2400
京东 家具 1800
淘宝 数码 2500
淘宝 家具 2500

        当然这只是涉及两个维度的随机组合,那试想一下如果是涉及n个维度呢,那组合方式岂不是有2^{1}+2^{2}+2^{3}+...+2^{n}种组合,写如此多的union显然对于我们代码开发和运行带来极大的不便,本文将给大家介绍一种对于经常需要对数据进行多维度的聚合分析的场景下非常好用的方法——grouping sets函数。

二、grouping sets函数

        其实grouping sets就是由多个group by联合起来,关系如下。  

select A , B from table group by grouping sets(A, B)  

等价于

select A , null as B  from table group by A

union all

select null as A ,  B  from table group by B

        针对于引入中的问题,用grouping sets函数:        

        代码:

select 
    渠道
    ,订单类型
    ,sum(订单金额)as 订单总金额
from temp
group by 渠道,订单类型
grouping sets(渠道,订单类型)

        结果:

渠道 订单类型 订单总金额
null 数码 4900
null 家具 4300
null null 9200
京东 null 4200
淘宝 null 5000
京东 数码 2400
京东 家具 1800
淘宝 数码 2500
淘宝 家具 2500

        可以看出,通过grouping sets函数,极大提高我们的开发效率,即使有更多维度组合的增加,只需要在grouping sets函数中新增即可,当然案例中姓名不具有实质性分组聚合意义,数据的展示问题需要做进一步处理,但相较于大量的union,grouping sets函数已经可以极大的对代码进行调优。

        当然grouping sets函数也可以有其他使用方法:只查询渠道存在、订单类型存在的结果:

        代码:

select 
    渠道
    ,订单类型
    ,sum(订单金额)as 订单总金额
from temp
group by 城市,渠道,订单类型
grouping sets(渠道,订单类型)

        结果:

渠道 订单类型 总金额
null 数码 4900
null 家具 4300
null null 9200
京东 null 4200
淘宝 null 5000

三、其他函数 

3.1 grouping( )

  grouping函数用来区分NULL值,这里NULL值有2种情况,一是原本表中的数据就为NULL,二是由字段是否选中生成的NULL值。

        代码:

select 
    渠道
    ,订单类型
    ,sum(订单金额) as 订单总金额
    ,grouping(渠道) ga
    ,grouping(订单金额) gb
from temp
group by 城市,渠道,订单类型
grouping sets(渠道,订单类型)

        结果:

渠道 订单类型 订单总金额 ga gb
null 数码 4900 1 0
null 家具 4300 1 0
null null 9200 1 1
京东 null 4200 0 1
淘宝 null 5000 0 1
京东 数码 2400 0 0
京东 家具 1800 0 0
淘宝 数码 2500 0 0
淘宝 家具 2500 0 0

 3.2 grouping_id( )

  grouping_id函数也是计算分组级别的函数,注意如果要使用grouping_id函数那必须得有group by字句,而且group by字句的中的列与grouping_id函数的参数必须相等。比如group by A,B,那么必须使用grouping_id(A,B)。下面用一个等效关系来说明grouping_id()与grouping()的联系,grouping_id(A, B)等效于grouping(A) + grouping(B),但要注意这里的+号不是算术相加,它表示的是二进制数据组合在一起,比如grouping(A)=1,grouping(B)=1,那么grouping_id(A, B)=11B,也就是十进制数3。

   代码:

select 
    渠道
    ,订单类型
    ,sum(订单金额) as 订单总金额
    ,grouping(渠道) ga
    ,grouping(订单金额) gb
    ,grouping_id(渠道,订单金额)gab
from temp
group by 城市,渠道,订单类型
grouping sets(渠道,订单类型)

        结果:

渠道 订单类型 订单总金额 ga gb gba
null 数码 4900 1 0 1
null 家具 4300 1 0 1
null null 9200 1 1 0
京东 null 4200 0 1 2
淘宝 null 5000 0 1 2
京东 数码 2400 0 0 3
京东 家具 1800 0 0 3
淘宝 数码 2500 0 0 3
淘宝 家具 2500 0 0 3

3.3 rollup和cube

        另外 group by rollup() 和 group by cube() 也和group by grouping sets() 有类似的用法。rollup是cube的一种特殊情况,和rollup一样,cube也是根据维度在分组的结果集中进行聚合操作。但是rollup只在层次上对数据进行聚合,而cube对所有的维度进行聚合。具有N个维度的列,cube需要2的N次方次分组操作,而rollup只需要N次分组操作。 带cube子句的group by会产生更多的分组统计数据。cube后的列有多少种组合(注意组合是与顺序无关的)就会有多少种分组。

假设有n个维度,rollup会有n个聚合:
rollup(a,b) 统计列包含:(a,b)、(a)、()
rollup(a,b,c) 统计列包含:(a,b,c)、(a,b)、(a)、()
……以此类推ing……

假设有n个纬度,cube会有2的n次方个聚合:
cube(a,b) 统计列包含:(a,b)、(a)、(b)、()
cube(a,b,c) 统计列包含:(a,b,c)、(a,b)、(a,c)、(b,c)、(a)、(b)、(c)、()
……以此类推ing……

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MYSQL——解决多维度随机组合查询场景:grouping sets函数 的相关文章

  • 是否可以使用“WHERE”子句来选择SQL语句中的所有记录?

    晚上好 我很好奇是否可以在 SQL 语句中创建一个 WHERE 子句来显示所有记录 下面一些解释 随机 SQL 语句 Java JSP示例 正常情况 String SqlStatement SELECT FROM table example
  • 获取查询的行号

    我有一个查询将返回一行 当表排序时 有什么方法可以找到我正在查询的行的行索引吗 我试过了rowid但当我期待第 7 行时却得到了 582 Eg CategoryID Name I9GDS720K4 CatA LPQTOR25XR CatB
  • SQL Server PIVOT 函数

    我有一个检索所有代理及其模块的查询 结果集将每个模块返回 1 行 SELECT am agentID AS agentid pa agentDisplayName agentdisplayname m ModuleName ModuleNa
  • 在 Oracle 中使用触发器记录对表的更改

    我的一门课有一个项目 当我们的两个表发生更改时 我们需要创建一个日志 插入 更新 删除 我们需要使用Oracle触发器和PL SQL 在日志文件中 我们需要记录用户ID 日期时间 IP地址和事件 插入 更新 删除 我知道如何设置触发器 但我
  • PreparedStatement setnull方法中Types.INTEGER和Types.NULL的区别

    下面的说法有什么区别 PreparedStatement setNull 1 java sql Types NULL and PreparedStatement setNull 1 java sql Types INTEGER 第一个指示驱
  • SQL Server 相当于 MySQL 的 USING

    在 MySQL 中 当您连接不同表中具有相同名称的列时 可以在连接中使用关键字 USING 例如 这些查询产生相同的结果 SELECT FROM user INNER JOIN perm USING uid SELECT FROM user
  • 消息 102,级别 15,状态 1,第 1 行“ ”附近的语法不正确

    我试图从临时表中查询 但不断收到此消息 Msg 102 Level 15 State 1 Line 1 Incorrect syntax near 有人能告诉我问题是什么吗 是因为要转换吗 查询是 select compid 2 conve
  • 如何通过循环变量在 dbt 中多次运行 SQL 模型?

    我有一个 dbt 模型 测试模型 接受地理变量 zip state region 在配置中 我想通过循环变量来运行模型三次 每次使用不同的变量运行它 问题是 我有一个如下所示的宏 它将变量附加到输出表名称的末尾 即运行测试模型 with z
  • 从一个sql服务器选择到另一个sql服务器?

    我想将一台服务器 Data Old S1 中的一个表 T1 在 DB1 中 中的数据选择到另一台服务器 Data Latest S2 中的另一个表 T2 在 DB2 中 中的数据 我怎样才能做到这一点 请注意服务器的命名方式 查询也应该考虑
  • SQLSTATE[HY000] [2002] 资源暂时不可用 - mysql - innodb 和 pdo

    在我的错误日志中得到大量结果 如下所列 数据库中的所有表都是 innodb 并且就与这些表的任何交互而言 一切都是带有准备好的语句的 pdo 正如我所说 所有错误几乎与下面列出的错误相同 但发生在几个不同的页面上 无论页面如何 错误行始终指
  • 对具有许多索引的表进行缓慢的批量插入

    我尝试将数百万条记录插入到具有 20 多个索引的表中 在上次运行中 每 100 000 行花费了 4 个多小时 并且查询在 3 5 天后被取消 您对如何加快速度有什么建议吗 我怀疑是索引太多的原因 如果你也这么认为 如何在操作前自动删除索引
  • INNER JOIN 可用作 SELECT,但不能用作 DELETE [重复]

    这个问题在这里已经有答案了 为什么这个有语法错误 DELETE FROM print mailing request pmr INNER JOIN person p ON p id pmr person AND p email LIKE T
  • 这是过滤数据并防止 SQL 注入和其他攻击的安全方法吗?

    我创建了两个简单的函数来在插入数据进入 mysql 查询之前对其进行过滤 对于表单字段 我还使用正则表达式来单独检查每个字段 Form filter function filter var HTML is not allowed var s
  • MySQL 中的 UDF 性能

    我注意到 当查询在 SELECT 或 WHERE 子句中调用 UDF 时 MySQL 查询执行时间的性能会呈指数级下降 有问题的 UDF 查询本地表以返回标量值 因此它们不仅执行算术表达式 而且充当相关子查询 我通过简单地删除 UDF 并使
  • 使用 xmlagg 时出现子查询错误和太多值

    我在连接许多大型表中的所有数据时遇到问题 我昨天对此提出了问题 但不幸的是 listagg 似乎不是一个好的选择 链接子查询返回多行 https stackoverflow com questions 54651144 subquery r
  • 如何对 SQL Server Express 进行实时更改

    我一直在使用 VS studio 开发一个 ASP NET Web 应用程序 我正在使用 SQL Server Express 在开发过程中 我一直在我的服务器上测试我的网络应用程序 每次我需要更新数据库时 我都会简单地删除旧数据库 位于我
  • 在 Sql Server 中启用 DTD 支持

    我有各种 xml 文档需要存储在数据库列中 这些文档包含对 DTD 的引用 并且 SQL Server 不会导入 xml 因为它存在安全风险 如何在数据库上启用 DTD 支持 以便它可以让我插入 xml 内容 你必须CONVERT首先 MS
  • MySql 复合索引

    我们使用 MySql 作为我们的数据库 以下查询在 mysql 表 大约 2500 万条记录 上运行 我在这里粘贴了两个查询 查询运行得太慢 我想知道更好的复合索引是否可以改善这种情况 你知道最好的综合指数是什么吗 并建议我这些查询是否需要
  • PLSQL 中的时区转换

    我需要将系统日期和时间转换为特定时区 例如东部时间 我无法假设我当前的时区 如何在plsql中转换它 请帮我 假设你有一个TIMESTAMP WITH TIME ZONE 例如systimestamp 您可以使用AT TIME ZONE句法
  • 执行存储过程时 ExecuteNonQuery() 返回 -1

    我正在尝试在 Visual Studio 中执行存储过程 下面给出 CREATE PROCEDURE dbo addStudent stuName varchar 50 address varchar 100 tel varchar 15

随机推荐

  • vsftpd服务器搭建与管理

    安装vsftpd rpm包 mount dev cdrom mnt cd mnt Server cp vsftpd 2 0 5 16 el5 i386 rpm usr usr rpm ivh vsftpd 2 0 5 16 el5 i386
  • 【HTML】解决恶意script脚本输入问题

    项目场景 提示 这里简述项目相关背景 HTML script 安全验证 程序永远不可以相信用户的输入 问题描述 系统做安全测试 发现系统中允许直接调用用户输入的脚本内容 如 系统加载完 会重复执行这个脚本 原因分析 提示 这里填写问题的分析
  • 2021-09-30 学习记录:渐变线的制作

    如上所示渐变线 写法如下 part 4 width 320 remh height 2 remh background image linear gradient 136deg rgba 39 101 150 0 0 rgba 39 221
  • log4j.properties配置详解

    stone 的 log4j配置详解 Log4J的配置文件 Configuration File 就是用来设置记录器的级别 存放器和布局的 它可接key value格式的设置或xml格式的设置信息 通过配置 可以创建出Log4J的运行环境 1
  • 操作系统类型

    unix freebsd VxWorks Solaris Windows xp 7 8 10 Linux Redhat Ubuntu SUSE CentOS mobile Android ios symbian embeded system
  • 前端插件之 Select2 介绍及使用

    Select2是一款基于JQuery的下拉列表插件 主要用来优化select 支持单选和多选 同时也支持分组显示 列表检索 远程获取数据等众多好用的功能 项目地址 select2 org 基本使用 需要用到的JS和CSS文件位于项目代码下的
  • 彻底理解线程

    优质资源分享 学习路线指引 点击解锁 知识定位 人群定位 Python实战微信订餐小程序 进阶级 本课程是python flask 微信小程序的完美结合 从项目搭建到腾讯云部署上线 打造一个全栈订餐系统 Python量化交易实战 入门级 手
  • h2database BTree 设计实现与查询优化思考

    h2database 是使用Java 编写的开源数据库 兼容ANSI SQL89 既实现了常规基于 BTree 的存储引擎 又支持日志结构存储引擎 功能非常丰富 死锁检测机制 事务特性 MVCC 运维工具等 数据库学习非常好的案例 本文理论
  • Python爬虫(七)学习提取网页中所有链接

    import re import urllib request def getlink url headers User Agent Mozilla 5 0 Windows NT 10 0 WOW64 AppleWebKit 537 36
  • Android OpenGL ES抗锯齿

    多重采样MSAA GLSurfaceView设置多重采样 抗锯齿EGLConfigChooser author weiss email kleinminamo gmail com created 2018 7 3 public class
  • Quartz2.2.0 产生misfire条件参数misfireThreshold和misfire策略详细说明

    首先 misfire产生的条件是 misfire的时间间隔大于配置里设置的misfireThreshold值 就认为是misfire了 错失触发了 比如 13 07 24开始执行 重复执行5次 开始执行时 quartz已经计算好每次调度的时
  • rk3588:failed to open rknpu module, need to insmod rknpu dirver!

    1 permission denied sudo chmod R 777 userdata 2 sudo E 系统中已有的python test py 大概是环境变量这块的问题 sudo E一下就行了
  • 情境领导者-第二章、领导风格

    文章目录 情境领导者 第二章 领导风格 故事 背景 独裁式与民主式的领导风格 工作行为 关系行为 态度与行为 领导风格 风格一 S1 风格二 S2 风格三 S3 风格四 S4 结束语 情境领导者 第二章 领导风格 故事 罗杰斯 简单地说 我
  • Unity3D-5.4.1f-Rain Storm Effects插件应用及车辆前挡风玻璃简易雨刮器制作

    Unity3D 5 4 1f Rain Storm Effects插件应用及车辆前挡风玻璃简易雨刮器制作 作者Ghost Light 1 使用的雨天天气模拟插件是Rain Storm Effects Rain Storm Effects的基
  • mysql 字段拼接_mysql 字符串拼接,你知道几种方式?

    第一种 mysql自带语法CONCAT string1 string2 此处是直接把string1和string2等等的字符串拼接起来 无缝拼接哦 说明 此方法在拼接的时候如果有一个值为NULL 则返回NULL 如 1 SELECT CON
  • shell入门第三课 case语句

    虽然if elif语言可以做多项选择 但是使用case在有大量选择的情况下 更为合理 case语句与C语言的case有些相似 可以根据条件选择对应的语句执行 1 形式 case语句 case 变量 in 模式11 模式12 表达式 模式21
  • 区块链节点和区块区别_《区块链百问百答》-区块链的节点竞选,到底是什么...

    上期讲解的区块链在医疗领域的应用 你看了吗 本期视频将解答大家关于节点竞选的困惑 现在跟随由LemoChain策划的 区块链百问百答 来认识一下吧 https www zhihu com video 1139492556072271872
  • 删除字符串最后一个字符的几种方法

    偶然看到的 记录一下 以免忘记 字符串 string s 1 2 3 4 5 目标 删除最后一个 方法 1 用的最多的是Substring 这个也是我一直用的 s s Substring 0 s Length 1 2 用 RTrim 这个我
  • 网络安全-php安全知识点

    目录 语法与注释 输出 变量 弱类型安全 超级全局常量 函数 常用 字符串相关 正则表达式 子字符串位置 数据库相关 mysqli pdo 伪协议相关 反序列化漏洞 serialize函数 unserialize函数 魔法函数 举例 写给和
  • MYSQL——解决多维度随机组合查询场景:grouping sets函数

    一 引入 注意 通常用在构建数据集市和复杂随机组合场景查询时使用 对于经常需要对数据进行多维度的聚合分析的场景 您既需要对A列做聚合 也要对B列做聚合 同时要对A B两列做聚合 因此需要多次使用union all 案例 比如此处有一张表te