Oracle数据库从入门到精通-分组统计查询

视频课程:李兴华 Oracle从入门到精通

视频课程学习者:阳光罗诺

视频来源:51CTO学院

整体内容:

  1. 统计函数的使用
  2. 分组统计查询的实现
  3. 对分组的数据过滤

统计函数

在之前我们就学习过一个COUNT()函数,这个函数的主要作用是统计一张表之中的数据量的个数。和它功能与之类似的常用函数有五个:

  • 统计个数COUNT():根据表中的实际数据量返回结果。
  • 求和SUM():是针对于数字的统计
  • 平均值AVG():是针对数字的统计
  • 最小值MIN():各种数据类型都支持。
  • 最大值MAX():各种数据类型都支持。

范例:验证各个函数

代码示例:

1 SELECT COUNT(*) 人数, AVG(sal)员工平均工资,SUM(sal)每月总支出,MAX(sal) 最高工资, MIN(sal)最低工资
2
3 FROM emp;

但是这些函数是允许和其他的函数嵌套的。

范例:统计出公司的平均雇佣年限。

代码示例:

1 SELECT AVG(MONTHS_BETWEEN(SYSDATE,hiredate)/12)
2 FROM emp;

范例:求出最早和最晚的雇佣日期(找到公司最早雇佣的雇员,以及公司最近雇佣的雇员日期)

代码示例:

1 SELECT MAX(hiredate) 最晚,MIN(hiredate) 最早 FROM emp;

以上的几个操作函数,在表中没有数据的时候,只有COUNT()函数会返回结果,其他的都是null。

范例:统计Bonus表

代码示例:

1 SELECT COUNT(*) 人数, AVG(sal)员工平均工资,SUM(sal)每月总支出,MAX(sal) 最高工资, MIN(sal)最低工资
2
3 FROM bonus;

在图中我们可以清楚的发现,此时只有COUNT()函数会返回最终的结果,即使没有数据也会返回0,而其他的统计函数结果都是null。

  实际上针对于COUNT()函数有三种使用形式:【面试题】

  • COUNT(*):可以准确的返回表中的全部记录数。
  • COUNT(字段):统计不为null的所有数据量。
  • COUNT(DISTINCT 字段):消除重复数据之后的结果。

范例:统计查询一

代码示例:

1 SELECT COUNT(*),COUNT(empno),COUNT(comm) FROM emp;

范例:查询二

代码示例:

1 SELECT COUNT(DISTINCT JOB) FROM emp;

分组统计

分组的前提是存在有重复,1但是允许单独一行记录进行分组。

如果要进行分组应该使用GROUP BY子句来完成,那么此时的语法结构形式如下:

语法结构:


【④选出所需要的数据列】SELECT [DISTINCT] *  分组列[别名],分组列[别名],分组列[别名]······

【①确定数据来源(行和列的集合)】FROM 表名称 [别名],表名称 [别名],······

【②筛选数据行】[WHERE 限定条件此时的条件可以是多个语法结构。

【③针对于筛选的行分组】[GROUP BY 分组字段,分组字段,······]

数据排序】[ORDER BY 排序字段 [ASC|DESC] 可以设置多个]

范例:根据部门编号分组,查询出每一个部门的编号、人数、平均工资。

代码示例:

1 SELECT deptno,count(*),avg(sal)
2
3 FROM emp
4
5 GROUP BY deptno;

范例:根据职位分组,统计出每一个职位的人数,最低工资与最高工资。

代码示例:

1 SELECT job,count(*),MAX(sal),MIN(sal)
2
3 FROM emp
4
5 GROUP BY job;

查询结果如图:

在GROUP BY 子句中,之所以使用麻烦,是因为分组的时候有一些约定条件。

  • 如果查询不适用GROUP BY子句,那么在SELECT子句中只允许出现统计函数,其他任何字段不允许出现。

错误代码:


正确代码:


SELECT empno,COUNT(*) FROM emp;

错误提示:

第 1 行出现错误:

ORA-00937: 不是单组分组函数


SELECT COUNT(*) FROM emp;

  • 如果查询中使用了额GROUP BY子句,那么SELECT子句中只允许出现分组字段、统计函数,其他任何字段都不允许出现。

错误代码:


正确代码:


SELECT ename,job,COUNT(*) FROM emp GROUP BY job;

错误提示:

第 1 行出现错误:

ORA-00979: 不是 GROUP BY 表达式


SELECT job,COUNT(*) FROM emp GROUP BY job;

  • 统计函数允许嵌套,但是嵌套之后的SELECT子句里面只允许出现嵌套函数,而不允许任何字段,包括分组字段。

错误代码:


正确代码:


SELECT deptno,MAX(AVG(sal)) FROM emp GROUP BY deptno;

错误提示:

第 1 行出现错误:

ORA-00937: 不是单组分组函数


SELECT MAX(AVG(sal)) FROM emp GROUP BY deptno;

多表查询与分析统计(重点)

对于GROUP BY子句而言,是在WHERE子句之后执行的,所以在使用时可以进行限定查询,也可以进行多表查询。

范例:查询出每个部门的名称、部门人数、平均工资。

  • 确定要使用的数据表

      • dept表:部门名称
      •   emp表:统计数据
  • 确定已知的关联字段。
      •     雇员与部门:emp.deptno = dept.deptno;

第一步:查询出每一个部门的名称、雇员编号(COUNT(empno))、基本工资(AVG(sal))。

代码示例:

1 SELECT d.dname,e.empno,e.sal
2
3 FROM emp e,dept d
4
5 WHERE e.deptno=d.deptno;

第二步:此时的查询结果中对于部门名称部分出现了重复的内容,按照分组来讲,只要是出现了数据的重复,那么就可以进行分组,只不过此时的分组是针对于临时表(查询结果),既然确定了dname上存在有重复记录,那么就直接针对于dname分组即可。

代码示例:

1 SELECT d.dname,COUNT(e.empno),AVG(e.sal)
2
3 FROM emp e,dept d
4
5 WHERE e.deptno=d.deptno
6
7 GROUP BY d.dname;

第三步:在dept表中存在有四个部门信息,而此时的要求也是统计所有的部门名称,如果发现数据不完整,立刻使用外连接。

代码示例:

1 SELECT d.dname,COUNT(e.empno),AVG(e.sal)
2
3 FROM emp e,dept d
4
5 WHERE e.deptno=d.deptno(+)
6
7 GROUP BY d.dname;

范例:查询每个部门的编号、名称、位置、部门人数、平均工资。

第一步:查询每一个部门的编号、名称、位置、雇员编号(COUNT())、工资(AVG(sal)).

代码示例:

1 SELECT d.deptno,d.dname,d.loc,e.empno,e.sal
2
3 FROM emp e,dept d
4
5 WHERE e.deptno(+)=d.deptno;

第二步:此时发现三个列(dept列)同时发生着重复,那么就可以进行多字段分组。

代码示例:

1 SELECT d.deptno,d.dname,d.loc,COUNT(e.empno),AVG(e.sal)
2
3 FROM emp e,dept d
4
5 WHERE e.deptno(+)=d.deptno
6
7 GROUP BY d.deptno,d.dname,d.loc;

HAVING子句

现在要求查询出每个职位的名称,职位的平均工资,但是要求显示的职位的平均工资高于2000.

即:按照职位先进行分组,同时统计出每个职位的平均工资。随后要求只显示那些平均工资高于2000的职位信息,那么既然现在要针对于显示的数据进行筛选,自然就会首先想到WHERE子句,于是有了如下的代码:

范例:代码示例:


错误代码:


SELECT job,AVG(sal)

FROM emp

WHERE AVG(sal)

GROUP BY job;


错误提示:

第 3 行出现错误:

ORA-00934: 此处不允许使用分组函数

此时直接告诉用户,WHERE子句中不允许出现统计函数(分组函数)。因为GROUP BY子句在WHERE子句之后执行的。那么此时执行WHERE子句时还没有进行分组,那么就自然无法进行统计。此时我们就可以使用HAVING子句来完成。

SQL语法结构:

【⑤选出所需要的数据列】SELECT [DISTINCT] *  分组列[别名],分组列[别名],分组列[别名]······

【①确定数据来源(行和列的集合)】FROM 表名称 [别名],表名称 [别名],······

【②筛选数据行】[WHERE 限定条件]  此时的条件可以是多个语法结构。

【③针对于筛选的行分组】[GROUP BY 分组字段,分组字段,······]

【③针对于筛选的行分组】[HAVING 分组过滤]

【⑥数据排序】[ORDER BY 排序字段 [ASC|DESC] 可以设置多个]

范例:使用HAVING子句

代码示例:

1 SELECT job,AVG(sal)
2
3 FROM emp
4
5 GROUP BY job
6
7 HAVING AVG(sal)>2000;

HAVING实在GROUP BY分组之后才进行的筛选,在HAVING里面可以直接使用统计函数。

说明:关于WHERE与HAVING的区别?

  1. WHERE子句在GROUP BY分组之前进行筛选,指的是选出那些可以参与分组的数据。并且在WHERE子句中不允许使用统计函数
  2. HAVING子句是在WHERE分组之后执行的,那么就可以使用统计函数。

分组案例:

范例:显示所有销售人员的工作名称以及从事同一个工作的雇员的月工资的总和,并且要求满足从事同一工作的月工资的合计大于5000,显示的结果按照月工资合计的升序排列。

第一步:查询所有非销售人员的信息,WHERE子句即可实现限定查询。

代码示例:

1 SELECT * FROM emp WHERE job<>‘SALESMAN‘;

查询结果:

第二步:按照职位进行分组,而后求出月工资的总支出。

代码示例:

1 SELECT job,SUM(sal)
2 FROM emp
3 WHERE job<>‘SALESMAN‘
4 GROUP BY job;

查询结果:

第三步:分组后的数据进行再次的筛选,使用HAVING子句。

代码示例:

1 SELECT job,SUM(sal)
2 FROM emp
3 WHERE job<>‘SALESMAN‘
4 GROUP BY job
5 HAVING SUM(sal)>5000;

查询结果:

第四步:按照月工资的合计升序排列。使用ORDER BY子句。

代码示例:

 1 SELECT job,SUM(sal)
 2
 3 FROM emp
 4
 5 WHERE job<>‘SALESMAN‘
 6
 7 GROUP BY job
 8
 9 HAVING SUM(sal)>5000
10
11 ORDER BY SUM(sal);

查询结果:

范例:统计所有领取佣金和布领取佣金的人数、平均工资。

代码示例:

1 SELECT comm,AVG(sal)
2
3 FROM  emp
4
5 GROUP BY comm;

查询结果:

使用GROUP BY子句会把每一个种子值当作一个分组,所以此时不可能直接使用GROUP BY。

查询出所有领取佣金的雇员的人数、平均工资。————直接使用WHERE子句。不需要使用GROUP BY子句

代码示例:

1 SELECT ‘领取佣金‘ info,COUNT(*),AVG(sal)
2 FROM emp
3 WHERE comm IS NOT  NULL;

查询结果:

查询出所有不领取佣金的雇员的人数、平均工资。————直接使用WHERE子句。不需要使用GROUP BY子句

代码示例:

1 SELECT ‘不领取佣金‘ info,COUNT(*),AVG(sal)
2 FROM emp
3 WHERE comm IS NULL;

查询结果:

既然此时两个查询结果返回的结构完全相同,那么我们就直接连接即可。

原文地址:https://www.cnblogs.com/launolife/p/9383104.html

时间: 2024-10-17 10:11:37

Oracle数据库从入门到精通-分组统计查询的相关文章

oracle数据库从入门到精通之四

序列是oracle中较为重要的概念事务对于ddl是不起作用的查询,更新,数据表,约束这些个概念要掌握. 在许多数据库之中都会存在一种数据类型--自动增长列,它能够创建流水号12c之前并没有提供这样一个自动增长的列,如果想要使用自动增长的列可以用序列来完成.序列属于数据库对象的创建过程,属于ddl的分类范畴,对于序列而言,会在数据字典中保存select * from user_sequences;时间戳+序列 如果要想使用序列则可以使用如下两个伪列nextval:取得序列下一个内容值.每一次调用序

Greenplum 分布式数据库开发入门到精通(架构、部署、管理、开发和调优)【课程分享】

Greenplum 分布式数据库开发入门到精通(架构.部署.管理.开发和调优) 对这个课程有兴趣的朋友,可以加我qq2059055336和我联系 课程大纲 1 Greenplum架构 什么是Greenplum Greenplum体系结构 Greenplum高可用性架构 2 安装Greenplum 配置环境 安装并初始化GPDB系统 启停数据库 配置GP系统 3 分布式数据库存储 数据是如何存储的 分布策略 4 GBDB查询处理 查询命令的执行 SQL查询处理机制 并行查询计划 5 角色权限及客户

Greenplum分布式数据库开发入门到精通

Greenplum分布式数据库开发入门到精通(架构.部署.管理.开发和调优)课程分类:Hadoop适合人群:初级课时数量:41课时用到技术:GP.MapReduce编程.装载和卸载数据涉及项目:角色权限及客户端认证管理咨询qq:1840215592双十一全场5折,前所未有的最低价,详情查看:http://www.ibeifeng.com/dou1111.html课程针对人群本课程适合于有一定java基础知识,对数据库和sql语句有一定了解,熟练使用linux系统的技术人员,特别适合于想换工作或寻

Oracle+11g+从入门到精通下载 &#652784;

下载地址: http://www.gqylpy.com/di/18 <Oracle 11g 从入门到精通>PDF高清完整版-下载 目录 编辑 第1章 了解Oracle 1.1 Oracle中的基本概念 1.1.1 数据库 1.1.2 实例 1.1.3 用户与模式 1.2 Oracle安装 1.2.1 Oracle的应用结构 1.2.2 安装环境 1.2.3 管理系统服务 1.3 Oracle工具 1.3.1 使用SQL*Plus 1.3.2 使用Ouacle Enterprise Manage

Oracle数据库基础入门培训视频课程_Oracle视频教程培训

课程目标 Oracle视频教程,本套风哥oracle教程培训入门学习内容包括Oracle版本介绍,Oracle基本概念,Oracle物理结构,Oracle结构,Oracle数据文件,Oracle控制文件,Oracle参数文件,Oracle启动与停止,Oracle高用性架构,Oracle数据库备份与恢复,Oracle单机/OracleRAC/OracleDataGuard等相关基础等. 适用人群 IT相关从业人员,非IT相关人员 课程简介 视频学习地址:http://edu.51cto.com/c

04.风哥Oracle数据库实战入门-Oracle安装配置视频教程

04.风哥Oracle数据库实战入门-Oracle安装配置视频教程链接:https://pan.baidu.com/s/1UDhT_A_e62sZshQ5n2toYQ 提取码:pqca 请分享链接到5个QQ IT交流群后,加入以下QQ群找群主获取更多免费视频. 更多视频教程,请加入QQ群(只加一个即可):189070296336282998 更多视频课程请点击:http://www.itpux.com/oracle.html 原文地址:http://blog.51cto.com/oracle18

Oracle数据库基础入门《一》Oracle服务器的构成

Oracle数据库基础入门<一>Oracle服务器的构成 Oracle 服务器是一个具有高性能和高可靠性面向对象关系型数据库管理系统,也是一 个高效的 SQL 语句执行环境. Oracle 服务器具备以下的特点: ● 能够可靠的进行多用户环境下大量数据的处理,允许多用户同时访问相同的数据. ● 保证数据访问的高性能. ● 有效防止对数据的非法访问. ● 对于故障恢复提供高效的解决方案. 一.Oracle 服务器的总体结构 Oracle 服务器同运行在操作系统下的很多程序一样,通过在后台运行一组

010.简单查询、分组统计查询、多表连接查询(sql实例)

-------------------------------------day3------------ --添加多行数据:------INSERT [INTO] 表名 [(列的列表)] --SELECT UNION --SELECT 'HAHA',1,32--UNION ALL --全部显示/显示重复数据 即使集合相同--UNION---------将查询的两个结果集合并.结构必须一致 -->常见面试题 --SELECT 'HEHE',2,33------将查询结果添加到列表中(子查询)IN

003.分组统计查询和表连接查询

--分组统计查询 group by having 1 select 分组字段 ,聚合函数 2 having 后常跟聚合函数,也可以跟分组字段 3 where 后不可以直接跟聚合函数 4 where(筛选行) -group by (分组) -having (筛选组) --表连接查询 1 笛卡尔积 (交叉连接 cross join) a*b A) SELECT * FROM A,B B) SELECT * FROM A CROSS JOIN B 2 内连接 原理: 将两个表中关联字段相等的行查询出来