数据库的数据分组GROUPBY
1、数据分组⼊门
数据分组⽤来将数据分为多个逻辑组,从⽽可以对每个组进⾏聚合运算。SQL语句中使⽤
GROUP BY⼦句进⾏分组,使⽤⽅式为“GROUP BY 分组字段”。分组语句必须和聚合函数⼀
起使⽤,GROUP BY⼦句负责将数据分成逻辑组,⽽聚合函数则对每⼀个组进⾏统计计算。
虽然GROUP BY⼦句常常和聚合函数⼀起使⽤,不过GROUP BY⼦句并不是不能离开聚合函数⽽单独使⽤。
SELECT FAge FROM T_Employee
GROUP BY FAge  //查看公司员⼯有哪些年龄段
需要注意的是GROUP BY⼦句的位置,GROUP BY⼦句必须放到SELECT语句的之后,如果SELECT语句有WHERE⼦句,则GROUP BY⼦句必须放到WHERE语句的之后
SELECT FAge FROM T_Employee
WHERE FSubCompany = 'Beijing'
GROUP BY FAge
需要分组的所有列都必须位于GROUP BY⼦句的列名列表中,也就是没有出现在GROUP BY⼦句中的列(聚合函数除外)是不能放到SELECT语句后的列名列表中的。
SELECT FAge,FSalary FROM T_Employee
GROUP BY FAge  //错误的,因为不存在能够统⼀代表本组⼯资⽔平的FSalary字段
SELECT FAge,AVG(FSalary) FROM T_Employee
GROUP BY FAge  //可以对FSalary使⽤聚合函数
GROUP BY⼦句中可以指定多个列,只需要将多个列的列名⽤逗号隔开即可。指定多个分组规则以后,数据库系统将按照定义的分组顺序来对数据进⾏逐层分组,⾸先按照第⼀个分组列进⾏分组,然后在每个⼩组内按照第⼆个分组列进⾏再次分组……逐层分组,从⽽实现“组中组”的效果,⽽查询的结果集是以最末⼀级分组来进⾏输出的。
SELECT FSubCompany,FDepartment FROM T_Employee
GROUP BY FSubCompany,FDepartment
2、数据分组与聚合函数
SELECT FAge,COUNT(*) AS CountOfThisAge FROM T_Employee
GROUP BY FAge  //查看每个年龄段的员⼯的⼈数
SELECT FSubCompany,FAge,COUNT(*) AS CountOfThisSubCompAge FROM
T_Employee
GROUP BY FSubCompany,FAge  //统计每个分公司的年龄段的⼈数
上⾯的执⾏结果是按照数据库系统默认的年龄进⾏排序的,为了更容易的按照每个分公司进⾏查看,我们可以指定按照FSubCompany字段进⾏排序,带ORDER BY的SQL语句如下:
SELECT FSubCompany,FAge,COUNT(*) AS CountOfThisSubCompAge FROM
T_Employee
GROUP BY FSubCompany,FAge
ORDER BY FSubCompany
“COUNT(*)”对每⼀个分组统计总数,这样就可以统计出每个公司每个年龄段的员⼯的⼈数了。
SUM、AVG、MIN、MAX也可以在分组中使
SELECT FSubCompany,SUM(FSalary) AS FSalarySUM FROM T_Employee
GROUP BY FSubCompany  //统计每个公司中的⼯资的总值
SELECT FDepartment,SUM(FSalary) AS FSalarySUM FROM T_Employee
GROUP BY FDepartment  //统计每个垂直部门中的⼯资的平均值
groupby分组SELECT FDepartment,MIN(FAge) AS FAgeMIN,MAX(FAge) AS FAgeMAX FROM T_Employee
GROUP BY FDepartment  //统计每个垂直部门中员⼯年龄的最⼤值和最⼩值
3、H AVIN G 语句
有的时候需要对部分分组进⾏过滤,⽐如只检索⼈数多余1个的年龄段
SELECT FAge,COUNT(*) AS CountOfThisAge FROM T_Employee
GROUP BY FAge
WHERE COUNT(*)>1
以上SQL语句数据库系统会提⽰语法错误,这是因为聚合函数不能在WHERE语句中使⽤,必须使⽤HAVING⼦句来代替
SELECT FAge,COUNT(*) AS CountOfThisAge FROM T_Employee
GROUP BY FAge
HAVING COUNT(*)>1
HAVING语句中也可以像WHERE语句⼀样使⽤复杂的过滤条件
SELECT FAge,COUNT(*) AS CountOfThisAge FROM T_Employee
GROUP BY FAge
HAVING COUNT(*) =1 OR COUNT(*) =3 //检索⼈数为1个或者3个的年龄段,
也可以使⽤IN操作符来实现上⾯的功能,SQL语句如下:
SELECT FAge,COUNT(*) AS CountOfThisAge FROM T_Employee
GROUP BY FAge
HAVING COUNT(*) IN (1,3)
HAVING语句能够使⽤的语法和WHERE⼏乎是⼀样的,不过使⽤WHERE的时候GROUP BY⼦句要位于WHERE⼦句之后,⽽使⽤HAVING⼦句的时候GROUP BY⼦句要位于HAVING⼦句之前,⽐如下⾯的SQL是错误的:
SELECT FAge,COUNT(*) AS CountOfThisAge FROM T_Employee
HAVING COUNT(*) IN (1,3)
GROUP BY FAge
需要特别注意,在HAVING语句中不能包含未分组的列名,⽐如下⾯的SQL语句是错误的:
SELECT FAge,COUNT(*) AS CountOfThisAge FROM T_Employee
GROUP BY FAge
HAVING FName IS NOT NULL
执⾏的时候数据库系统会提⽰类似如下的错误信息:
HAVING ⼦句中的列'T_Employee.FName' ⽆效,因为该列没有包含在聚合函数或GROUP BY ⼦句中。
需要⽤WHERE语句来代替HAVING,修改后的SQL语句如下:
SELECT FAge,COUNT(*) AS CountOfThisAge FROM T_Employee
WHERE FName IS NOT NULL
GROUP BY FAge
以上摘⾃《程序员的SQL ⾦典》

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。