玩转数据库之 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
- WPF备忘录(3)如何从 Datagrid 中获得单元格的内容与 使用值转换器进行绑定数据的转换IValueConverter
- WPF备忘录(2)WPF获取和设置鼠标位置与progressbar的使用方法
- WPF文字修饰——上、中、下划线与基线
- 微信公众平台数据接口正式对所有认证公众号开放
- 参考基因组没有,经费也没那么多,怎么办?
- .Net下SQLite的DBHelp
- 数据库进程间通信解决方案之MQ
- 【学术】算法交易的神经网络:强化经典策略
- java.util.logging 例子
- WPF命令(Command)介绍、命令和数据绑定集成应用
- lncRNA实战项目-第六步-WGCNA相关性分析
- 【项目】Github上的一个简单项目:用人工智能预测大学录取概率
- lncRNA实战项目-第五步-差异表达的mRNA和lncRNA
- WPF--模板选择
- 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 数组属性和方法
- 实战django(二)--登录实现记住我
- org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.gong.mybatis.da
- 【python-leetcode378-二分查找】有序矩阵中的第k小元素
- 使用cookie来记录用户登录次数,为何次数不更新
- (二)golang--windows下vscode的安装以及go环境的配置
- mybatis文件映射之使用#取值时的一些规则
- 【论文笔记】Improved Residual Networks for Image and Video Recognition(ResNet新变体:IResNet)
- SQL语句在MYSQL中的运行过程和各个组件的介绍
- (五)golang--常用的一些玩意
- 关于MYSQL 的日志系统
- (六)golang--变量
- springmvc之文件上传
- (七)golang--变量之基本数据类型(看这篇就够了)
- Mybatis学习笔记(五)Mybatis中已经显示数据已修改但数据库中记录未更新问题
- 【自然语言处理(一)】相关基础技能