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

  

时间: 2024-08-15 08:39:15

玩转数据库之 Group by Grouping的相关文章

java中list集合的内容,如何使用像数据库中group by形式那样排序

java中list集合的内容,如何使用像数据库中group by形式那样排序,比如:有一个 List<JavaBean> 他中包含了一些如下的内容JavaBean:name    money(名称)  (金额) 来源A   100来源B   200来源C   300来源B   6600来源A   99800<数据1> 最后想实现的是:如果假设这些数据在数据库中,那么通过 select name,sum(money) from Table group by name 该语句得到的Li

面试笔试常考的mysql 数据库操作group by

IT 面试中,数据库的相关问题基本上属于必考问题,而其中关于sql语句也是经常考察的一个重要知识点. 下面介绍下sql语句中一个比较重要的操作group by,他的重要行一方面体现在他的理解困难度,一方面体现应用中的长见性. 首先,给出一个studnet学生表: CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(30) DEFAULT NULL, `sex` tinyint(1) DEFAU

oracle数据库报表汇总函数grouping

前两天同事问一个oracle使用grouping完成一个统计报表的功能,这个函数帅呆了.开发分组报表直接一个SQL就搞定. grouping(columnA)函数的意思:当前行如果是由rollup汇总产生的,那么columnA这个字段值为1否则为0 元数据: 通过grouping查询后的数据: sql: select decode(grouping(f_line)+grouping(f_workarea),1,'小计',2,'总计',f_workarea) f_workarea, decode(

mysql数据库中group by和sum一起使用语句的简单介绍

一.SUM 用以求和.ps,所有的人的总数和. 二.sum和group by一起使用 如果需要查询的是男生和女生的各自的总年龄怎么查呢?做法为:把人按性别来分组,然后用SUM函数来求和 CREATE TABLE test_table ( NAME VARCHAR(50) COMMENT '姓名', age INT COMMENT '年龄', sex TINYINT COMMENT '性别' );

MySQL数据库:group分组

group by:分组 GroupBy语句从英文的字面意义上理解就是"根据(by)一定的规则进行分组(Group)".它的作用是通过一定的规则将一个数据集划分成若干个小的区域,然后针对若干个小区域进行数据处理. # group by 字段名 having 条件表达式 分组查询 select sName from elogs inner join students on sID = sNo group by sNo having count(sid)>=2; # having 与

Oracle中group by 的扩展函数rollup、cube、grouping sets

Oracle的group by除了基本用法以外,还有3种扩展用法,分别是rollup.cube.grouping sets,分别介绍如下: 1.rollup 对数据库表emp,假设其中两个字段名为a,b,c. 如果使用group by rollup(a,b),首先会对(a,b)进行group by ,然后对 a 进行 group by ,最后对全表进行 group by 操作. 如下查询结果: 查询语句 Select deptno,job,sum(sal) from emp group by r

Group By 多个分组集小结 --GROUPING SETS,GROUP BY CUBE,GROUP BY ROLLUP,GROUPING(),GROUPING_ID()

T-SQL 多个分组集共有三种 GROUPING SETS, CUBE, 以及ROLLUP, 其中 CUBE和ROLLUP可以当做是GROUPING SETS的简写版 示例数据库下载: http://files.cnblogs.com/files/haseo/TSQL2012.rar GROUPING SETS 列出所有你设置的分组集 SELECT shipperid, YEAR(shippeddate) AS shipyear, COUNT(*) AS numorders FROM Sales

非嵌入式数据库 软件很难普及 玩大

pg没有 嵌入版我不用 TMD 以后 写软件 就得玩 嵌入式数据库否则 根本 做不大的我是前车之鉴,人家 网页都几十万用户了 我还徘徊在5万以下原因就是 客户端软件的 安装巨麻烦 ,我用的是 sqlserver2005每个用户都安装 sql2005可见 有多失败光售后问题 就能让人 死好几回非嵌入式数据库 软件很难普及 玩大以后 再写软件 就一个exe,不需要安装 可以用weblone再网页中运行,也可以下载下来直接运行 不需要安装

SQL Server2008 程序设计 汇总 GROUP BY,WITH ROLLUP,WITH CUBE,GROUPING SETS(..)

--SQL Server2008 程序设计 汇总 GROUP BY ,WITH ROLLUP  WITH CUBE  GROUPING SET(..) /******************************************************************************** *主题:SQL Server2008 程序设计 汇总 group by ,WITH ROLLUP  WITH CUBE *说明:本文是个人学习的一些笔记和个人愚见 *      有很多