玩转数据库之 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

  

Group by Grouping的更多相关文章

  1. 玩转数据库之 Group by Grouping

    有的时候我们要从数据库里把数据组织成树结构再展现到页面上 像下面这样 今天我们用Group 和Grouping实现它,并总结一下它俩. 先看一下概念,再用代码一点一点去理解它们,最后我会给出完整的代码 ...

  2. Group By Grouping Sets

    Group by分组函数的自定义,与group by配合使用可更加灵活的对结果集进行分组,Grouping sets会对各个层级进行汇总,然后将各个层级的汇总值union all在一起,但却比单纯的g ...

  3. Oracle PL/SQL之GROUP BY GROUPING SETS

    [转自] http://blog.csdn.net/t0nsha/article/details/6538838 使用GROUP BY GROUPING SETS相当于把需要GROUP的集合用UNIO ...

  4. GROUP BY GROUPING SETS 示例

    --建表 create table TEst1 ( ID ), co_CODE ), T_NAME ), Money INTEGER, P_code ) ); --插入基础数据 insert into ...

  5. group by <grouping sets(...) ><cube(...)>

    GROUP BY      GROUPING SETS() 后面将还会写学习 with cube,  with rollup,以及将它们转换为标准的GROUP BY的子句GROUP SET(), CU ...

  6. SQL GROUP BY GROUPING SETS,ROLLUP,CUBE(需求举例)

    实现按照不同级别分组统计 关于GROUP BY 中的GROUPING SETS,ROLLUP,CUBE 从需求的角度理解会更加容易些. 需求举例: 假如一所学校只有两个系, 每个系有两个专业, 每个专 ...

  7. (4.6)sql2008中的group by grouping sets

    最近遇到一个情况,需要在内网系统中出一个统计报表.需要根据不同条件使用多个group by语句.需要将所有聚合的数据进行UNION操作来完成不同维度的统计查看. 直到发现在SQL SERVER 200 ...

  8. SQL Server 之 GROUP BY、GROUPING SETS、ROLLUP、CUBE

    1.创建表 Staff CREATE TABLE [dbo].[Staff]( ,) NOT NULL, ) NULL, ) NULL, ) NULL, [Money] [int] NULL, [Cr ...

  9. [Oracle] Group By 语句的扩展 - Rollup、Cube和Grouping Sets

    常常写SQL语句的人应该知道Group by语句的主要使用方法是进行分类汇总,以下是一种它最常见的使用方法(依据部门.职位分别统计业绩): SELECT a.dname,b.job,SUM(b.sal ...

随机推荐

  1. Hadoop上传文件的报错

    baidu了很多,都说防火墙,datanode没有正常启动的问题,可是检查了都是正常,后来还是在老外的网站上找到了解决的方法 修改了/etc/security/limits.conf文件,上传成功 这 ...

  2. CSharp设计模式读书笔记(8):桥接模式(学习难度:★★★☆☆,使用频率:★★★☆☆)

    桥接模式(Bridge Pattern): 将抽象部分与它的实现部分分离,使它们都可以独立地变化.它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模 ...

  3. C和指针 (pointers on C)——第一章:高速启动

    大多数人并不认为有几类人猿学校计划非常赞同C学习好,然后看多本书. 仅仅作为读书笔记写.有时还包括一些题目和答案. 这样的公开栏,这两种玉引砖敲,对于自勉,鼓励王! 第一章:手 我每次都是复习的来写. ...

  4. c# WebBrowser开发参考资料

    原文:c# WebBrowser开发参考资料 c# WebBrowser开发参考资料,所有资料的采集均来自网上 话说有了WebBrowser类,终于不用自己手动封装SHDocVw的AxWebBrows ...

  5. c# 文件同步服务器,iis 集群 ,代码同步(二)

    打算自己做一个 集群 代码同步软件. 基于Socket 和 FileSystemWatcher .

  6. 【ThinkingInC++】66、pointer Stash的使用

    头文件PStash.h /** * 书本:[ThinkingInC++] * 功能:pointer Stash的头文件 * 时间:2014年10月5日14:33:15 * 作者:cutter_poin ...

  7. Humming Bird A20 SPI2驱动编译

    Humming Bird A20 SPI2使用编译 Yao.GUET 2014-07-17,请注明出处:http://blog.csdn.net/Yao_GUET A20上带有4个spi接口,因为Hu ...

  8. android如何判断服务是否正在运行状态

    如何检查后台服务(Android的Service类)是否正在运行?我希望我的Activity能够显示Service的状态,然后我可以打开或者关闭它. /** * 判断服务是否处于运行状态. * @pa ...

  9. ActiveReports 9实战教程(2): 准备数据源(设计时、运行时)

    原文:ActiveReports 9实战教程(2): 准备数据源(设计时.运行时) 在上讲中<ActiveReports 9实战教程(1): 手把手搭建环境Visual Studio 2013 ...

  10. Sql Server 存储过程中查询数据无法使用 Union(All)

    原文:Sql Server 存储过程中查询数据无法使用 Union(All) 微软Sql Server数据库中,书写存储过程时,关于查询数据,无法使用Union(All)关联多个查询. 1.先看一段正 ...