转载于:http://www.studyofnet.com/news/247.htmlhtml
本文导读:在实际SQL应用中,常常须要进行分组聚合,即将查询对象按必定条件分组,而后对每个组进行聚合分析。建立分组是经过GROUP BY子句实现的。与WHERE子句不一样,GROUP BY子句用于概括信息类型,以汇总相关数据。GROUP BY的做用是经过必定的规则将一个数据集划分红若干个小的区域,而后针对若干个小区域进行数据处理。ide
在SQL Server中使用的分组查询是ORDER BY子句,使用ORDER BY子句要同聚合函数配合使用才能完成分组查询,在SELECT查询的字段中若是字段没有使用聚合函数就必须出如今ORDER BY子句中(即SELECT后边的字段名要么出如今聚合函数中,要么在ORDER BY子句中使用)函数
在分组查询中还能够配合使用HAVING子句,定义查询条件。spa
使用group by进行分组查询xml
在使用group by关键字时,在select列表中能够指定的项目是有限制的,select语句中仅许如下几项:htm
〉被分组的列
〉为每一个分组返回一个值得表达式,例如用一个列名做为参数的聚合函数对象
group by 有一个原则,就是 select 后面的全部列中,没有使用聚合函数的列,必须出如今 group by 后面(重要)get
group by实例数学
实例一it
数据表:
姓名 科目 分数
张三 语文 80
张三 数学 98
张三 英语 65
李四 语文 70
李四 数学 80
李四 英语 90
指望查询结果:
姓名 语文 数学 英语
张三 80 98 65
李四 70 80 90
代码
create table testScore
(
tid int primary key identity(1,1),
tname varchar(30) null,
ttype varchar(10) null,
tscor int null
)
go
---插入数据
insert into testScore values ('张三','语文',80)
insert into testScore values ('张三','数学',98)
insert into testScore values ('张三','英语',65)
insert into testScore values ('李四','语文',70)
insert into testScore values ('李四','数学',80)
insert into testScore values ('李四','英语',90)
select tname as '姓名' ,
max(case ttype when '语文' then tscor else 0 end) '语文',
max(case ttype when '数学' then tscor else 0 end) '数学',
max(case ttype when '英语' then tscor else 0 end) '英语'
from testScore
group by tname
实例二
有以下数据:(为了看得更清楚,我并无使用国家代码,而是直接用国家名做为Primary Key)
国家(country) | 人口(population) |
中国 | 600 |
美国 | 100 |
加拿大 | 100 |
英国 | 200 |
法国 | 300 |
日本 | 250 |
德国 | 200 |
墨西哥 | 50 |
印度 | 250 |
根据这个国家人口数据,统计亚洲和北美洲的人口数量。应该获得下面这个结果。
洲 | 人口 |
亚洲 | 1100 |
北美洲 | 250 |
其余 | 700 |
代码
SELECT SUM(population),
CASE country
WHEN '中国' THEN '亚洲'
WHEN '印度' THEN '亚洲'
WHEN '日本' THEN '亚洲'
WHEN '美国' THEN '北美洲'
WHEN '加拿大' THEN '北美洲'
WHEN '墨西哥' THEN '北美洲'
ELSE '其余' END
FROM Table_A
GROUP BY CASE country
WHEN '中国' THEN '亚洲'
WHEN '印度' THEN '亚洲'
WHEN '日本' THEN '亚洲'
WHEN '美国' THEN '北美洲'
WHEN '加拿大' THEN '北美洲'
WHEN '墨西哥' THEN '北美洲'
ELSE '其余' END;
一样的,咱们也能够用这个方法来判断工资的等级,并统计每一等级的人数。SQL代码以下;
SELECT
CASE WHEN salary <= 500 THEN '1'
WHEN salary > 500 AND salary <= 600 THEN '2'
WHEN salary > 600 AND salary <= 800 THEN '3'
WHEN salary > 800 AND salary <= 1000 THEN '4'
ELSE NULL END salary_class,
COUNT(*)
FROM Table_A
GROUP BY
CASE WHEN salary <= 500 THEN '1'
WHEN salary > 500 AND salary <= 600 THEN '2'
WHEN salary > 600 AND salary <= 800 THEN '3'
WHEN salary > 800 AND salary <= 1000 THEN '4'
ELSE NULL END;
对于groupby后面通常都是跟一个列名,但在该例子中经过case语句使分组变得跟强大了。
实例三
有以下数据
国家(country) | 性别(sex) | 人口(population) |
中国 | 1 | 340 |
中国 | 2 | 260 |
美国 | 1 | 45 |
美国 | 2 | 55 |
加拿大 | 1 | 51 |
加拿大 | 2 | 49 |
英国 | 1 | 40 |
英国 | 2 | 60 |
按照国家和性别进行分组,得出结果以下
国家 | 男 | 女 |
中国 | 340 | 260 |
美国 | 45 | 55 |
加拿大 | 51 | 49 |
英国 | 40 | 60 |
代码
SELECT country,
SUM( CASE WHEN sex = '1' THEN
population ELSE 0 END), --男性人口
SUM( CASE WHEN sex = '2' THEN
population ELSE 0 END) --女性人口
FROM Table_A
GROUP BY country;
GROUP BY子句中的NULL值处理
当GROUP BY子句中用于分组的列中出现NULL值时,将如何分组呢?SQL中,NULL不等于NULL(在WHERE子句中有过介绍)。然而,在GROUP BY子句中,却将全部的NULL值分在同一组,即认为它们是“相等”的。
HAVING子句
GROUP BY子句分组,只是简单地依据所选列的数据进行分组,将该列具备相同值的行划为一组。而实际应用中,每每还须要删除那些不能知足条件的行组,为了实现这个功能,SQL提供了HAVING子句。语法以下。
SELECT column, SUM(column)
FROM table
GROUP BY column
HAVING SUM(column) condition value
说明:HAVING一般与GROUP BY子句同时使用。固然,语法中的SUM()函数也能够是其余任何聚合函数。DBMS将HAVING子句中的搜索条件应用于GROUP BY子句产生的行组,若是行组不知足搜索条件,就将其从结果表中删除。
HAVING子句的应用
从TEACHER表中查询至少有两位教师的系及教师人数。
实现代码:
SELECT DNAME, COUNT(*) AS num_teacher
FROM TEACHER
GROUP BY DNAME
HAVING COUNT(*)>=2

HAVING子句与WHERE子句的区别
HAVING子句和WHERE子句的类似之处在于,它也定义搜索条件。但与WHERE子句不一样,HAVING子句与组有关,而不是与单个的行有关。
一、若是指定了GROUP BY子句,那么HAVING子句定义的搜索条件将做用于这个GROUP BY子句建立的那些组。
二、若是指定WHERE子句,而没有指定GROUP BY子句,那么HAVING子句定义的搜索条件将做用于WHERE子句的输出,并把这个输出看做是一个组。
三、若是既没有指定GROUP BY子句也没有指定WHERE子句,那么HAVING子句定义的搜索条件将做用于FROM子句的输出,并把这个输出看做是一个组。
四、在SELECT语句中,WHERE和HAVING子句的执行顺序不一样。在本书的5.1.2节介绍的SELECT语句的执行步骤可知,WHERE子句只能接收来自FROM子句的输入,而HAVING子句则能够接收来自GROUP BY子句、WHERE子句和FROM子句的输入。