玩转数据库之 Group by Grouping
时间:2022-04-25
本文章向大家介绍玩转数据库之 Group by Grouping,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
有的时候我们要从数据库里把数据组织成树结构再展现到页面上
像下面这样
今天我们用Group 和Grouping实现它,并总结一下它俩。
先看一下概念,再用代码一点一点去理解它们,最后我会给出完整的代码
Group By : 语句用于结合合计函数,根据一个或多个列对结果集进行分组。
Grouping :指示是否聚合 GROUP BY 列表中的指定列表达式。 在结果集中,如果 GROUPING 返回 1 则指示聚合;
返回 0 则指示不聚合。 如果指定了 GROUP BY,则 GROUPING 只能用在 SELECT <select> 列表、HAVING 和 ORDER BY 子句中。
ROLLUP :生成简单的 GROUP BY 聚合行以及小计行或超聚合行,还生成一个总计行。
让我们先建一个数据库,并添加一些数据
use master
go
if exists(select 1 from sysdatabases where name ='MyGroupDB')
ALTER DATABASE MyGroupDB SET SINGLE_USER with ROLLBACK IMMEDIATE
drop database MyGroupDB
go
create database MyGroupDB
go
use MyGroupDB
go
create Table Category
(
Category_ID int identity(1,1),
Category_Name varchar(100)
)
go
create Table Product
(
Product_ID int identity(1,1),
CategoryID int ,
Product_Name varchar(100)
)
go
insert into Category values('手机')
insert into Category values('台式机')
insert into Category values('数码相机')
go
insert into Product values(1,'诺基亚')
insert into Product values(1,'三星')
insert into Product values(1,'苹果')
insert into Product values(2,'HP')
insert into Product values(2,'IBM')
insert into Product values(2,'Dell')
insert into Product values(3,'佳能')
insert into Product values(3,'尼康')
insert into Product values(3,'索尼')
go
看一下它们的数据
select *
from Category
left join Product on Category_ID = CategoryID
我们把它们用Group By分一下组
select Category_ID ,
Category_Name,
CategoryID,
Product_Name
from Category
left join Product on Category_ID = CategoryID
group by Category_ID ,CategoryID,Category_Name,Product_Name
我们看到这样和没有分组时展现的数据是一样的,让我们加上 ROLLUP 加上合计行
select Category_ID ,
Category_Name,
CategoryID,
Product_Name
from Category
left join Product on Category_ID = CategoryID
group by Category_ID ,CategoryID,Category_Name,Product_Name with rollup
我们看到了好多NULL数据,而且很有规律
这些规律我们可以用Grouping 看到
select Category_ID ,
GROUPING(Category_ID) as Category_IDGP,
Category_Name,
GROUPING(Category_Name) as Category_NameGP,
CategoryID,
GROUPING(CategoryID) as CategoryIDGP,
Product_Name,
GROUPING(Product_Name) as Product_NameGP
from Category
left join Product on Category_ID = CategoryID
group by Category_ID ,Category_Name,CategoryID,Product_Name with rollup
你会发现那些Null值就是Grouping 为1的时候
最后一行的合计是Categrory_ID的,我们不需要,CategoryID的合计我们也不需要我们要怎么去掉它们呢,在having 里
select Category_ID ,
GROUPING(Category_ID) as Category_IDGP,
CategoryID,
GROUPING(CategoryID) as CategoryIDGP,
Category_Name,
GROUPING(Category_Name) as Category_NameGP,
Product_Name,
GROUPING(Product_Name) as Product_NameGP
from Category
left join Product on Category_ID = CategoryID
group by Category_ID ,Category_Name,CategoryID,Product_Name with rollup
having GROUPING(Category_ID)=0 and GROUPING(CategoryID)=0
这样的结果 我们看到只有Product_Name的Grouping有为1 了
我们就是用它去实现这棵树
select
case GROUPING(Product_Name) when 1 then Category_Name else '' end as Category_Name,
case GROUPING(Product_Name) when 0 then Product_Name else '' end as Product_Name
from Category
left join Product on Category_ID = CategoryID
group by Category_ID ,Category_Name,CategoryID,Product_Name with rollup
having GROUPING(Category_ID)=0 and GROUPING(CategoryID)=0
order by Category_ID ,Product_Name
下面是完整的代码
use master
go
if exists(select 1 from sysdatabases where name ='MyGroupDB')
ALTER DATABASE MyGroupDB SET SINGLE_USER with ROLLBACK IMMEDIATE
drop database MyGroupDB
go
create database MyGroupDB
go
use MyGroupDB
go
create Table Category
(
Category_ID int identity(1,1),
Category_Name varchar(100)
)
go
create Table Product
(
Product_ID int identity(1,1),
CategoryID int ,
Product_Name varchar(100)
)
go
insert into Category values('手机')
insert into Category values('台式机')
insert into Category values('数码相机')
go
insert into Product values(1,'诺基亚')
insert into Product values(1,'三星')
insert into Product values(1,'苹果')
insert into Product values(2,'HP')
insert into Product values(2,'IBM')
insert into Product values(2,'Dell')
insert into Product values(3,'佳能')
insert into Product values(3,'尼康')
insert into Product values(3,'索尼')
go
select *
from Category
left join Product on Category_ID = CategoryID
--------------------------------------------------------
select Category_ID ,
Category_Name,
CategoryID,
Product_Name
from Category
left join Product on Category_ID = CategoryID
group by Category_ID ,CategoryID,Category_Name,Product_Name with rollup
--------------------------------------------------------
select Category_ID ,
GROUPING(Category_ID) as Category_IDGP,
Category_Name,
GROUPING(Category_Name) as Category_NameGP,
CategoryID,
GROUPING(CategoryID) as CategoryIDGP,
Product_Name,
GROUPING(Product_Name) as Product_NameGP
from Category
left join Product on Category_ID = CategoryID
group by Category_ID ,Category_Name,CategoryID,Product_Name with rollup
----------------------
select Category_ID ,
GROUPING(Category_ID) as Category_IDGP,
CategoryID,
GROUPING(CategoryID) as CategoryIDGP,
Category_Name,
GROUPING(Category_Name) as Category_NameGP,
Product_Name,
GROUPING(Product_Name) as Product_NameGP
from Category
left join Product on Category_ID = CategoryID
group by Category_ID ,Category_Name,CategoryID,Product_Name with rollup
having GROUPING(Category_ID)=0 and GROUPING(CategoryID)=0
-------------------------
select
case GROUPING(Product_Name) when 1 then Category_Name else '' end as Category_Name,
case GROUPING(Product_Name) when 0 then Product_Name else '' end as Product_Name
from Category
left join Product on Category_ID = CategoryID
group by Category_ID ,Category_Name,CategoryID,Product_Name with rollup
having GROUPING(Category_ID)=0 and GROUPING(CategoryID)=0
order by Category_ID ,Product_Name
- Kafka源码系列之Consumer高级API性能分析
- Kafka源码系列之源码解析SimpleConsumer的消费过程
- Spark调优系列之序列化方式调优
- Spark源码系列之foreach和foreachPartition的区别
- kafka源码系列之mysql数据增量同步到kafka
- Hbase源码系列之BufferedMutator的Demo和源码解析
- Kafka源码系列之0.10版本的Producer源码解析及性能点讲解
- Spark源码系列之spark2.2的StructuredStreaming使用及源码介绍
- Hbase源码系列之scan源码解析及调优
- spark源码系列之内部通讯的三种机制
- Hbase源码系列之regionserver应答数据请求服务设计
- 大数据基础系列之kafkaConsumer010+的多样demo及注意事项
- 大数据基础系列之kafka011生产者缓存超时,幂等性和事务实现
- 大数据基础系列之提交spark应用及依赖管理
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android图片压缩的实例详解
- Android编程之手机壁纸WallPaper设置方法示例
- 手把手教你在腾讯云上搭建hadoop3.x伪集群的方法
- Android从网络中获得一张图片并显示在屏幕上的实例详解
- Android ListView中headerview的动态显示和隐藏的实现方法
- Android编程使用Service实现Notification定时发送功能示例
- Android基于ViewFilpper实现文字LED显示效果示例
- Android ViewPager导航小圆点实现无限循环效果
- ViewPager打造轮播图Banner/引导页Guide
- Android 实现带字母索引的侧边栏功能
- Android实现简单底部导航栏 Android仿微信滑动切换效果
- Android中Handler与Message的简单实例
- Android 实现通知消息水平播放、无限循环效果
- 详解xamarin Android 实现ListView万能适配器
- android 设置wallpaper的操作方法