Oracle学习笔记(七)
九、高级查询(分组,子查询)
查询升级版:
需要用到三张表
员工表:
desc emp
EMPNO 员工号
ENAME 员工姓名
JOB 员工职位
MGR 老板员工号
HIREDATE 员工入职日期
SAL 员工月薪
COMM 员工奖金
DEPTNO 员工所在部门部门号
查看当前用户:
show users;
select * from emp;
部门表:
desc dept
deptno 部门号
dname 部门名称
LoC 部门地点
select * from dept;
工资级别表:
desc salgrade
GRADE 级别
LOSAL 级别最低薪水
HISAL 级别最高薪水
select * from salgrade;
十、分组查询
1、分组函数的概念
分组函数作用于一组数据,并对一组数据返回一个值
2、分组函数的使用
常用的分组函数:AVG、SUM、MIN、MAX、COUNT、WM_CONCAT(行转列)
(1)求出员工的平均工资和工资总额
select avg(SAL) as 平均工资,sum(SAL) as 工资总额 from emp;
(2)求出员工工资的最大值和最小值
select max(SAL) as 工资的最大值,min(SAL) as 工资的最小值 from emp;
(3)求出员工的总人数
select COUNT(*) as 总人数 from emp;
(4)查询部门数(去除重复)
select COUNT(distinct deptno) as 部门数 from emp;
(5)行转列
设置行宽
set linesize 200
col 部门中员工的姓名 for a60
select deptno as 部门号,wm_concat(ename) as 部门中员工的姓名 from emp group by deptno;
(6)分组函数与空值
a、统计员工的平均工资(三种方法统计薪水)
select sum(sal)/count(*) 一,sum(sal)/count(sal) 二, avg(sal) 三 from emp;
b、统计员工的平均奖金(三个值不相同)
select sum(comm)/count(*) 一,sum(comm)/count(comm) 二, avg(comm) 三 from emp;
注意:
分组函数会自动忽略空值
(7)在分组函数中使用NVl函数
注意:NVL函数使分组函数无法忽略空值
改写b
所有员工都统计
select sum(comm)/count(*) 一,sum(comm)/count(nvl(comm,0)) 二, avg(nvl(comm,0)) 三 from emp;
非空员工的统计
select sum(comm)/count(comm) 二, avg(comm) 三 from emp;
3、使用GROUP BY 子句数据分组
(1)求出employee表中各部门的平均工资,并按照部门号分组
select deptno 部门号,avg(sal) 平均工资 from emp group by deptno;
注意:
在select列表中所有未包含在组函数中的列都应该包含在group by子句中
就是select 列名一,列名二 from emp group by 列名一;
因为列名一不是列名二的内容,所有要加在group by 后面
(2)求每个部门的平均工资,要求显示:部门的平均工资
select avg(sal) 平均工资 from emp group by deptno;
注意:
包含在group by 子句中的列不必包含在select列表中
(3)使用多个列分组
查询员工的薪水总额
select deptno 员工号,job 工作,sum(sal) 总薪水 from emp group by deptno,job order by deptno;
修改语句:
edit
编辑后保存
执行语句:
/
(4)非法使用组函数
所包含与select列表中,而未包含于组函数中的列都必须包含于group by 子句中
经典错误
select deptno,count(ename) from emp;
正确形式:
select deptno,count(ename) from emp group by deptno;
4、使用HAVING子句过滤分组结果集
(1)求平均工资大于2000的部门
select deptno 部门号,avg(sal) 平均工资 from emp group by deptno having avg(sal)>2000;
where与having的区别
a、不能在where子句中使用组函数
b、可以在having子句中使用组函数
(2)查询10号部门的平均工资(where和having可以通用的情况)
select deptno 部门号,avg(sal) 平均工资 from emp group by deptno having deptno=10;
select deptno 部门号,avg(sal) 平均工资 from emp where deptno=10 group by deptno;
注意:
从SQL优化的角度看,尽量使用where,where使得分组记录数大大降低,从而提高效率
5、在分组查询中使用order by子句
(1)求每个部门的平均工资,要求显示:部门号,部门的平均工资,并且按照工资升序排列(可以按照:列、别名、表达式、序号进行排序)
select deptno 部门号,avg(sal) 平均工资 from emp group by deptno order by avg(sal);
写法二:
select deptno 部门号,avg(sal) 平均工资 from emp group by deptno order by 2;
追加降序命令:
a(后接两个或以上空格)
a desc
/
select deptno 部门号,avg(sal) 平均工资 from emp group by deptno order by 2 desc;
(2)分组函数的嵌套
求部门平均工资的最大值
思路:(a)通过avg函数求出每个部门的平均工资
(b)嵌套max函数求出部门平均工资的最大值
select max(avg(sal)) 平均工资 from emp group by deptno;
6、group by语句的增强
(1)按部门、不同的职位、统计工资总额,
按部门,统计工资总额
统计工资总额
select deptno 员工号,job 工作,sum(sal) 总薪水 from emp group by deptno,job order by deptno;
select deptno 员工号 sum(sal) 总薪水 from emp group by deptno
select sum(sal) 总薪水 from emp
上三句相加得下边一句话
break on deptno skip 2
set pagesize 30
select deptno,job,sum(sal) from emp group by rollup(deptno,job);(不可设置别名)
7、SQL*PLus的报表功能
报表包括:标题/页码/别名等
ttitle col 15 '我的报表' col 35 sql.pno 空15个列显示我的报表这个标题,空35个列
col deptno heading 部门号 标题设置为不猛号
col job heading 职位
col sum(sal) heading 工资总额
break on deptno skip 1
select deptno,job,sum(sal) from emp group by rollup(deptno,job);
保存一个目录中,get 文件路径
@路径执行
8、多表查询
(1)什么是多表查询?
从多个表中获取数据,就是多表查询
(2)迪卡尔集
例子演示:
create table dept_disk(
deptno number(5,0) primary key,
dname varchar2(20)
);
insert into dept_disk values(1,'开发部');
insert into dept_disk values(2,'行政部');
create table emp_disk(
emptno number(5,0),
ename varchar2(20),
sal number(5,0),
deptno number(5,0)
);
insert into emp_disk values(1,'开发部');
insert into emp_disk values(2,'行政部');
两包张表按照如下规则合并成一张表,叫做迪卡尔集表
(1)迪卡尔集表的列数,等于每张表的列数相加,迪卡尔集表的行数,等于每张表的行数相乘.得到笛卡尔全集
(2)多表查询的核心是连接条件.连接条件的个数,表的个数减一,两张表至少有一个连接条件.
注意:
(a)为了避免迪卡尔集,可以在where加入有效的连接条件.
(b)在实际运行环境下,应避免使用笛卡尔全集.
连接类型:
(3)等值连接
连接条件是个等号,就是等值连接
例子:查询员工信息,要求显示:员工号,姓名,月薪,部门名称
select e.empno as 员工号,e.ename as 姓名,e.sal as 月薪,d.dname as 部门名称 from emp e, dept d where e.deptno=d.deptno;
(4)不等值连接
例子:查询员工信息,要求显示:员工号,姓名,月薪,薪水等级(用between...and需要小值在前,大值在后)
select e.empno as 员工号,e.ename as 姓名,e.sal as 月薪, s.grade as 薪水等级 from emp e,salgrade s where e.sal between s.losal and s.hisal;
(5)外连接
例子:按部门统计员工人数,要求显示:部门号,部门名称,人数
select d.deptno as 部门号,d.dname as 部门名称,count(e.empno) as 人数 from dept d, emp e where e.deptno(+)=d.deptno group by d.deptno,d.dname;
注意:
(a)核心:通过外连接,把对于连接条件不成立的记录,仍然包含在最后的结果中
(b)左外连接:当条件不成立的时候,等号左边的表仍然被包含(等号右边加(+))
(c)右外连接:当连接条件不成立的时候,等号右边的表仍然被包含(等号左边加(+))
(6)自连接
例子:查询员工姓名和员工的老板姓名
连接条件员工的老板号等于老板的员工号
select e.ename as 员工姓名,b.ename as 老板姓名 from emp e,emp b where e.mgr=b.empno;
注意:
(a)核心:通过别名,将同一张表视为多张表
自连接存在的问题:
(1)自连接不做任何操作,得到的就是笛卡尔乘积
select count(*) from emp e,emp b;
(a)问题一:自连接不是和操作大表(因为自乘会有很大的数据)
解决方法:层次查询
说明:某些情况下,可以替代自连接,本质上是一个单表查询
(7)层次查询
原理:关系成成树状图
select level as 层次,empno as 员工号,ename as 员工姓名,sal as 月薪,mgr as 老板号 from emp connect by prior empno=mgr start with mgr is null order by 1;
优点:单表查询
缺点:没有自连接直观
Oracle学习笔记(七)的更多相关文章
- Oracle学习笔记七 锁
锁的概念 锁是数据库用来控制共享资源并发访问的机制. 锁用于保护正在被修改的数据 直到提交或回滚了事务之后,其他用户才可以更新数据 对数据的并发控制,保证一致性.完整性.
- Oracle学习笔记三 SQL命令
SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)
- (转)Qt Model/View 学习笔记 (七)——Delegate类
Qt Model/View 学习笔记 (七) Delegate 类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...
- oracle学习笔记第一天
oracle学习笔记第一天 --oracle学习的第一天 --一.几个基础的关键字 1.select select (挑选) 挑选出显示的--列--(可以多列,用“,”隔开,*表示所有列),为一条 ...
- Typescript 学习笔记七:泛型
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- python3.4学习笔记(七) 学习网站博客推荐
python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...
- Go语言学习笔记七: 函数
Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...
- Oracle学习笔记——点滴汇总
Oracle学习笔记——点滴汇总 http://www.botangdb.com/ Oracle GI = Grid Infrastructure = ASM + Cluster
随机推荐
- sublime text 3 配置优化
1.在用Sublime里编写代码时,需要把TAB键转换成四个空格. 菜单栏里点击:首选项-> 设置-用户(Preferences-> Setting-User)在弹出来的文本里,添加如下两 ...
- 渐进式 jpg 和 交错式 gif png 提高图片站体验
渐进式 jpg 和 交错式 gif png 提高图片站体验= 渐进式的JPG比原始JPG还要小!! 让图片性感的露给你看~google picasa 和 smashing magazine 都有用到搞 ...
- jdk版本对应数字
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springfr ...
- 打印进度条——(progress bar才是专业的)
# 打印进度条——(progress bar是专业的) import time for i in range(0,101,2): time.sleep(0.1) char_num = i//2 #打印 ...
- 【linux】less &&more
命令 : less [文件名] ...
- 面试总结之MISC(操作系统,网络,数学,软件开发,测试,工具,系统设计,算法)
操作系统 解释堆和栈的区别. 分配在堆的内存与分配在堆栈的内存有什么不同 分配在堆的内存要手动去释放 线程与进程的区别 多线程中栈与堆是公有的还是私有的 在多线程环境下,每个线程拥有一个栈和一个程序计 ...
- HTTP Error: 413 Request Entity Too Large的解决
昨天在使用PHP的CURL调用另一个项目的API:A时,出现了HTTP Error: 413 Request Entity Too Large的错误.而调用另一个API:B则没有这个错误. A的API ...
- Hive默认分割符
1.Hive默认的分隔符 Hive的表数据,不管导出到HDFS还是本地文件系统,如果用户在导出时没有指定分割符,那么Hive表的数据在写入文件时,会使用默认的分隔符作为列分隔符,该默认的分割是“CTR ...
- SpringBoot入门(1)
一.初始 ①.首先还是要创建一个maven工程 ②.然后编写Controller 让SpringBoot跑起来并不需要太多的代码,就能实现了我们平时要配置很多的功能,这是怎么做到的呢?我们就下面一个入 ...
- springboot 2.0 自动装配原理 以redis为例
当面试管问你springboot 和 普通spring 有什么区别? 您还在回答: 简化了配置 ,内置tomcat 等等 吗 ? 那只是皮毛, 最重要的还是自动化配置.一起来了解一下 第一步: 第二步 ...