Oracle_group by分组查询_深入
Posted 日月的弯刀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle_group by分组查询_深入相关的知识,希望对你有一定的参考价值。
Oracle_group by分组查询_深入
在SQL Server中使用的分组查询是ORDER BY子句,使用ORDER BY子句要同聚合函数配合使用才能完成分组查询,在SELECT查询的字段中如果字段没有使用聚合函数就必须出现在ORDER BY子句中(即SELECT后边的字段名要么出现在聚合函数中,要么在ORDER BY子句中使用)
在分组查询中还可以配合使用HAVING子句,定义查询条件。
使用group by进行分组查询
在使用group by关键字时,在select列表中可以指定的项目是有限制的,select语句中仅许以下几项:
〉被分组的列
〉为每个分组返回一个值得表达式,例如用一个列名作为参数的聚合函数
group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面(重要)
group by实例
实例一
数据表:
姓名 科目 分数
张三 语文 80
张三 数学 98
张三 英语 65
李四 语文 70
李四 数学 80
李四 英语 90
期望查询结果:
姓名 语文 数学 英语
张三 80 98 65
李四 70 80 90
代码
![](https://image.cha138.com/20210513/a37120adaf1e4dfbaf437953daf0f9bd.jpg)
![](https://image.cha138.com/20210513/1fdfa0f952124021a0675382a6cd07d8.jpg)
create table testScore
![](https://image.cha138.com/20210513/dbfe683fd4b14f7caa9cf736043e3e9e.jpg)
(
![](https://image.cha138.com/20210513/c58316d013064995b075b01a7f57995b.jpg)
tid int primary key identity(1,1),
![](https://image.cha138.com/20210513/a1307e803a844c3bb9bbb9a91574c1df.jpg)
tname varchar(30) null,
![](https://image.cha138.com/20210513/eb225bdafa0346c3803f15aceb88511d.jpg)
ttype varchar(10) null,
![](https://image.cha138.com/20210513/97604887dc81449287466c99869a4ea1.jpg)
tscor int null
![](https://image.cha138.com/20210513/089576421ee6451e82441b021802b436.jpg)
)
![](https://image.cha138.com/20210513/e54f377f72eb4af982a22bade736948f.jpg)
go
![](https://image.cha138.com/20210513/26e977e2f2ee454cb7b48b0846e662e0.jpg)
---插入数据insert into testScore values (\'张三\',\'语文\',80)
![](https://image.cha138.com/20210513/70cf600128c54d5ca88c8046d2a38cb2.jpg)
insert into testScore values (\'张三\',\'数学\',98)
![](https://image.cha138.com/20210513/5473958602134d8e9337d696f85591ee.jpg)
insert into testScore values (\'张三\',\'英语\',65)
![](https://image.cha138.com/20210513/be4010dc829a4c5b82194bc24a53bebc.jpg)
insert into testScore values (\'李四\',\'语文\',70)
![](https://image.cha138.com/20210513/7f59b35ce1114cb095c2cf49921f5555.jpg)
insert into testScore values (\'李四\',\'数学\',80)
![](https://image.cha138.com/20210513/329ce745b69c47e9be82e05643ba2ace.jpg)
insert into testScore values (\'李四\',\'英语\',90)
![](https://image.cha138.com/20210513/914a5135f47a410a914b3be5d7c1ff65.jpg)
![](https://image.cha138.com/20210513/e4aef1a3927e4feca357aeede6325641.jpg)
![](https://image.cha138.com/20210513/635aef47eb3340a8a3a048cc53b14d2d.jpg)
select tname as \'姓名\' ,
![](https://image.cha138.com/20210513/642b6804031745c19bfa42c101ec14c6.jpg)
max(case ttype when \'语文\' then tscor else 0 end) \'语文\',
![](https://image.cha138.com/20210513/ff6f8831ffdc433db236ad7f4f89e1f7.jpg)
max(case ttype when \'数学\' then tscor else 0 end) \'数学\',
![](https://image.cha138.com/20210513/c8f6cd2828524389985965b85094dde8.jpg)
max(case ttype when \'英语\' then tscor else 0 end) \'英语\'
![](https://image.cha138.com/20210513/a3c90650aa4c407fb181d80e92c62661.jpg)
from testScore
![](https://image.cha138.com/20210513/78002c5a1788473d8b77b5756530dd40.jpg)
group by tname
![](https://image.cha138.com/20210513/86242c3b098742b793f28a29f4019c6d.jpg)
实例二
有如下数据:(为了看得更清楚,我并没有使用国家代码,而是直接用国家名作为Primary Key)
国家(country) | 人口(population) |
中国 | 600 |
美国 | 100 |
加拿大 | 100 |
英国 | 200 |
法国 | 300 |
日本 | 250 |
德国 | 200 |
墨西哥 | 50 |
印度 | 250 |
根据这个国家人口数据,统计亚洲和北美洲的人口数量。应该得到下面这个结果。
洲 | 人口 |
亚洲 | 1100 |
北美洲 | 250 |
其他 | 700 |
代码
![](https://image.cha138.com/20210513/f504ec2868ee45379d21484bcab74123.jpg)
![](https://image.cha138.com/20210513/b259fa1c641f4866a89c4a31b99d726c.jpg)
SELECT SUM(population),
![](https://image.cha138.com/20210513/7280e6d5ea2c4be2bc346e0e1e005f32.jpg)
CASE country
![](https://image.cha138.com/20210513/231699103b244417904dcb8c1306134e.jpg)
WHEN \'中国\' THEN \'亚洲\'
![](https://image.cha138.com/20210513/c649df490a3b4247b31dd4b837762527.jpg)
WHEN \'印度\' THEN \'亚洲\'
![](https://image.cha138.com/20210513/7266a5c69a2f4fb2a7b5dc97e1af5ae8.jpg)
WHEN \'日本\' THEN \'亚洲\'
![](https://image.cha138.com/20210513/3995929e46ea4fd58977c27ce2ac70d8.jpg)
WHEN \'美国\' THEN \'北美洲\'
![](https://image.cha138.com/20210513/854e7f1dfd9e4dcf80f4858597841610.jpg)
WHEN \'加拿大\' THEN \'北美洲\'
![](https://image.cha138.com/20210513/7a8a778f49194032acff669a033475ea.jpg)
WHEN \'墨西哥\' THEN \'北美洲\'
![](https://image.cha138.com/20210513/6a90ea14f4f24423824c70fe81fa3297.jpg)
ELSE \'其他\' END
![](https://image.cha138.com/20210513/87e5750540544810b691be627a7a27d1.jpg)
FROM Table_A
![](https://image.cha138.com/20210513/ff75df3e68684e8da682946fbdcf5dcb.jpg)
GROUP BY CASE country
![](https://image.cha138.com/20210513/47bbaa34636845ed8ddad54783165fd7.jpg)
WHEN \'中国\' THEN \'亚洲\'
![](https://image.cha138.com/20210513/86b9c18515e9490a91bf9de1e4617419.jpg)
WHEN \'印度\' THEN \'亚洲\'
![](https://image.cha138.com/20210513/e12b4a26e6464fb9a1c42da3ee1b6e17.jpg)
WHEN \'日本\' THEN \'亚洲\'
![](https://image.cha138.com/20210513/9a9450f043244014bb9909c1c3e44515.jpg)
WHEN \'美国\' THEN \'北美洲\'
![](https://image.cha138.com/20210513/204954abcbf34870885df202575c89df.jpg)
WHEN \'加拿大\' THEN \'北美洲\'
![](https://image.cha138.com/20210513/5474df6e3fab45adb9e87d56c0597427.jpg)
WHEN \'墨西哥\' THEN \'北美洲\'
![](https://image.cha138.com/20210513/5232f530b2b94d078e658ad007ce3b08.jpg)
ELSE \'其他\' END;
![](https://image.cha138.com/20210513/bafef1521d444baa96a2e77186d2b7ee.jpg)
同样的,我们也可以用这个方法来判断工资的等级,并统计每一等级的人数。SQL代码如下;
![](https://image.cha138.com/20210513/9ed5909939f84330963278bb77fdbfb9.jpg)
![](https://image.cha138.com/20210513/45e7ed7547c84730a4357dcce82aa494.jpg)
SELECT
![](https://image.cha138.com/20210513/691997b474244db38fdc8651b97585a0.jpg)
CASE WHEN salary <= 500 THEN \'1\'
![](https://image.cha138.com/20210513/80d2a3e432b546a9831ffd2e0b5d1b66.jpg)
WHEN salary > 500 AND salary <= 600 THEN \'2\'
![](https://image.cha138.com/20210513/49efcb3a0f684c7b8c5b9b7a65b56cdc.jpg)
WHEN salary > 600 AND salary <= 800 THEN \'3\'
![](https://image.cha138.com/20210513/a8fcb30703424b0bb17ee291cf2ba8e5.jpg)
WHEN salary > 800 AND salary <= 1000 THEN \'4\'
![](https://image.cha138.com/20210513/8109019d7b764e98ade29225d264da95.jpg)
ELSE NULL END salary_class,
![](https://image.cha138.com/20210513/a4541158dbbc484887008392154486ce.jpg)
COUNT(*)
![](https://image.cha138.com/20210513/e97f5378080c4ef4aa2a2190d1d3abe1.jpg)
FROM Table_A
![](https://image.cha138.com/20210513/169b3cb3345a464f99d402e51426712a.jpg)
GROUP BY
![](https://image.cha138.com/20210513/040453a56ee741cfb19f85ac3b11c804.jpg)
CASE WHEN salary <= 500 THEN \'1\'
![](https://image.cha138.com/20210513/79f18f5044f5435289677930f6406fa7.jpg)
WHEN salary > 500 AND salary <= 600 THEN \'2\'
![](https://image.cha138.com/20210513/cacdaf7e9cfe4492b3da8609c18f6da0.jpg)
WHEN salary > 600 AND salary <= 800 THEN \'3\'
![](https://image.cha138.com/20210513/e10a758177274fbc9c8e7b12715dfcf7.jpg)
WHEN salary > 800 AND salary <= 1000 THEN \'4\'
![](https://image.cha138.com/20210513/9f83f9391c6543dba9dee9baa66b29a0.jpg)
ELSE NULL END;
![](https://image.cha138.com/20210513/7a72c1cb161545db932c6772f6af6dd3.jpg)
对于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 |
代码
![](https://image.cha138.com/20210513/faacdc120b30476e8ea3ae6841e14192.jpg)
![](https://image.cha138.com/20210513/4d5d95eee2e74620b6005c4986266fa5.jpg)
SELECT country,
![](https://image.cha138.com/20210513/6d2fbc26fdcf466c8ed1cd6becffe544.jpg)
SUM( CASE WHEN sex = \'1\' THEN
![](https://image.cha138.com/20210513/4b6da88c2a844cb8b8586f93c74df7a2.jpg)
population ELSE 0 END), --男性人口SUM( CASE WHEN sex = \'2\' THEN
![](https://image.cha138.com/20210513/c26e43424cf74e359d8b347f991c0729.jpg)
population ELSE 0 END) --女性人口FROM Table_A
![](https://image.cha138.com/20210513/8c77387f448b46c1bc516dd1cdbaca83.jpg)
GROUP BY country;
![](https://image.cha138.com/20210513/b6fb01837f0b41b6a31a12dee3d9ddbc.jpg)
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表中查询至少有两位教师的系及教师人数。
实现代码:
![](https://image.cha138.com/20210513/722bd5db9ca34c93a738bb6758749dc3.jpg)
SELECT DNAME, COUNT(*) AS num_teacher
![](https://image.cha138.com/20210513/7820ae94e1654cfd993eb5869b5fae5e.jpg)
FROM TEACHER
![](https://image.cha138.com/20210513/deff176b68cd4cef897e35cf7afbc1c5.jpg)
GROUP BY DNAME
![](https://image.cha138.com/20210513/6468a2bab5e741ff91d08b35dd236fdc.jpg)
HAVING COUNT(*)>=2![](https://image.cha138.com/20210513/12b3a88f903e4ebda48dd172ce770947.jpg)
HAVING子句与WHERE子句的区别
HAVING子句和WHERE子句的相似之处在于,它也定义搜索条件。但与WHERE子句不同,HAVING子句与组有关,而不是与单个的行有关。
1、如果指定了GROUP BY子句,那么HAVING子句定义的搜索条件将作用于这个GROUP BY子句创建的那些组。
2、如果指定WHERE子句,而没有指定GROUP BY子句,那么HAVING子句定义的搜索条件将作用于WHERE子句的输出,并把这个输出看作是一个组。
3、如果既没有指定GROUP BY子句也没有指定WHERE子句,那么HAVING子句定义的搜索条件将作用于FROM子句的输出,并把这个输出看作是一个组。
4、在SELECT语句中,WHERE和HAVING子句的执行顺序不同。在本书的5.1.2节介绍的SELECT语句的执行步骤可知,WHERE子句只能接收来自FROM子句的输入,而HAVING子句则可以接收来自GROUP BY子句、WHERE子句和FROM子句的输入。
以上是关于Oracle_group by分组查询_深入的主要内容,如果未能解决你的问题,请参考以下文章
Java操作Elasticsearch6实现group by分组查询