Oracle学习笔记(八)
十一、子查询
1、子查询概述
学习子查询的原因
事例:查询工资比SCOTT高的员工信息
思路:1、scott的工资
select sal from emp where ename='SCOTT';
2、比3000高的员工信息
select * from emp where sal>3000;
子查询方式:
select * from emp where sal> (select sal from emp where ename='SCOTT');
2、子查询的使用
子查询注意的10个问题
(a)子查询语法中的小括号
(b)子查询的书写风格
格式:
select *
from emp
where sal> (select sal
from emp
where ename='SCOTT');
(c)可以使用子查询的位置:where,select,having,from
select事例
单行子查询,只返回一条记录
事例:
select empno,ename,sal,(select job from emp where empno=7830) 第四列 from emp;
多行子查询,返回多条记录
having事例:
10号部门的平均工资:
select deptno,avg(sal) from emp group by deptno having avg(sal)>(select max(sal) from emp where deptno=30);
from事例:
select * from(select empno,ename,sal from emp);
(d)不可以使用子查询的位置:group by
不允许的情况:
select avg(sal) from emp group by (select deptno from emp);
(e)强调:from后面的子查询
(1)查询员工信息:员工号,姓名,月薪
select * from (select empno as 员工号,ename as 姓名,sal as 月薪 from emp);
(2)查询员工信息:员工号,姓名,月薪,年薪
select * from (select empno as 员工号,ename as 姓名,sal as 月薪,sal*12 as 年薪 from emp);
(f)主查询和子查询可以不是同一张表
事例:
查询部门名称是SALES的员工信息
select * from emp where deptno=(select deptno from dept where dname='SALES');
select e.* from emp e,dept d where e.deptno=d.deptno and d.dname='SALES';
(g)一般不在子查询中,使用排序,但在Top-N分析问题中,必须对子查询排序
事例:
找到员工表中工资最高的前三名,如下格式:
ROWNUM EMPNO ENAME SAL
1 7839 KING 5000
2 7788 SCOTT 3000
3 7902 FORD 3000
---------rownum 行号 伪劣
select rownum,empno,ename,sal from emp where rownum<=3 order by sal desc;
行号需要注意的两个问题:
行号永远按照默认的顺序生成
行号只能使用<,<=;不能使用>,>=
(h)一般先执行子查询,再执行主查询,但相关子查询例外
事例:
找到员工表中薪水大于本部门平均薪水的员工
select empno,ename,sal,(select avg(nvl(sal,0)) from emp where deptno=e.deptno) as 平均薪水
from emp e
where sal>(select avg(nvl(sal,0)) from emp where deptno=e.deptno);
3、子查询的类型
(i)单行子查询只能使用单行操作符,多行子查询只能使用多行操作符
单行操作符
操作符 含义
= equal to
> greater than
>= greater than or equal to
< less than
<= less than or equal to
<> Not equal to
多行操作符
操作符 含义
IN 等于列表中的任何一个
ANY 和子查询返回的任意一个值比较
ALL 和子查询返回的所有值比较
单行子查询:
事例:
查询员工信息,要求:
A、职位与7566员工一样
B、薪水大于7782员工的薪水
select * from emp where job =(select job from emp where empno=7566) and sal >(select sal from emp where empno=7782);
注意:单行子查询只能使用单行操作符
事例:
查询工资最低的员工信息
select * from emp where sal=(select min(sal) from emp);
事例:
查询最低工资大于20号部门最低工资的部门号和部门的最低工资
select deptno,min(sal) from emp group by deptno having min(sal)>(select min(sal) from emp where deptno=20);
多行子查询:
多行操作符:in
事例:
查询部门名称是SALES和ACCOUNTING的员工信息
select * from emp where deptno in (select deptno from dept where dname='SALES' or dname='ACCOUNTING');
select e.* from emp e, dept d where e.deptno=d.deptno and (d.dname='SALES' or dname='ACCOUNTING');
多行操作符:any
事例:
查询工资比30号部门任意一个员工高的员工信息
select * from emp where sal > any(select sal from emp where deptno=30);
select * from emp where sal > (select min(sal) from emp where deptno=30);
多行操作符:all
事例:
查询工资比30号部门所有员工高的员工信息
select * from emp where sal > all(select sal from emp where deptno=30);
select * from emp where sal > (select max(sal) from emp where deptno=30);
(j)注意:子查询中有null问题
单行:
子查询不返回任何行(错误的例子)
select ename,job from emp where job (select job from emp where ename='Tom');
事例:
查询不是老板的员工(错误)
select * from emp where empno not in (select mgr from emp);
正确
select * from emp where empno not in (select mgr from emp where mgr is not null);
4、综合事例
目标:
(1)灵活运用select语句解决实际的问题
(2)通过四个具体的示例,演示如何编写高效的查询语句
示例一:
分页查询显示员工信息:显示员工号,姓名,月薪
要求:(1)每页显示四条记录
(2)显示第二页的员工
(3)按照月薪降序排列
注意:rownum只能使用<,<=,不能使用>,>=
Oracle 通过拼接子查询方式实现分页操作
select r,empno,ename,sal
from (select rownum r,empno,ename,sal
from (select rownum,empno,ename,sal from emp order by sal desc) e1
where rownum<=8) e2
where r>=5;
查看伪列的行号
select rownum,r,empno,ename,sal
from (select rownum r,empno,ename,sal
from (select rownum,empno,ename,sal from emp order by sal desc) e1
where rownum<=8) e2
where r>=5;
示例二:
找到员工表中薪水大于本部门平均薪水的员工.
方法一:
select empno,ename,sal,(select avg(sal) from emp where deptno=e.deptno) as 平均薪水
from emp e
where sal>(select avg(sal) from emp where deptno=e.deptno);
方法二:
select e.empno,e.ename,e.sal, d.avgsal as 平均薪水
from emp e,(select deptno ,avg(sal) avgsal from emp group by deptno) d
where e.deptno=d.deptno and e.sal>d.avgsal;
执行计划设置:
explain plan for
select empno,ename,sal,(select avg(sal) from emp where deptno=e.deptno) as 平均薪水
from emp e
where sal>(select avg(sal) from emp where deptno=e.deptno);
查看执行计划:
select * from table(dbms_xplan.display);
执行计划设置:
explain plan for
select e.empno,e.ename,e.sal, d.avgsal as 平均薪水
from emp e,(select deptno ,avg(sal) avgsal from emp group by deptno) d
where e.deptno=d.deptno and e.sal>d.avgsal;
查看执行计划:
select * from table(dbms_xplan.display);
结论:相关子查询更加的快捷
示例三:
按部门统计员工人数,按照如下格式输出:
Total 1980 1981 1982 1987
======== ======= ========== ======== =========
14 1 10 1 2
注意:员工的入职年份已知
方法一(函数方式):
select count(*) Total,
sum(decode(to_char(hiredate,'YYYY'),'1980',1,0)) "1980",
sum(decode(to_char(hiredate,'YYYY'),'1981',1,0)) "1981",
sum(decode(to_char(hiredate,'YYYY'),'1982',1,0)) "1982",
sum(decode(to_char(hiredate,'YYYY'),'1987',1,0)) "1987"
from emp;
方法二(子查询方式):
select
(select count(*) from emp) Total,
(select count(*) from emp where to_char(hiredate,'yyyy')='1980') "1980",
(select count(*) from emp where to_char(hiredate,'yyyy')='1981') "1981",
(select count(*) from emp where to_char(hiredate,'yyyy')='1982') "1982",
(select count(*) from emp where to_char(hiredate,'yyyy')='1987') "1987"
from dual;
示例四:
============选课表===============
create table pm_ci(
CI_ID varchar2(20) not null,
STU_IDS varchar2(100)
);
insert into pm_ci values('1','1,2,3,4');
insert into pm_ci values('2','1,4');
==========学生表========
create table pm_stu(
STU_ID varchar2(20) not null,
STU_NAME varchar2(20)
);
insert into pm_stu values('1','张三');
insert into pm_stu values('2','李四');
insert into pm_stu values('3','王五');
insert into pm_stu values('4','赵六');
要求查询以下结果:
CI_ID STU_NAME
==================== ===================
1 张三,李四,王五,赵六
2 张三,赵六
提示:
1、需要进行两个表的连接查询,为两个表都取别名
2、使用instr(a,b)函数,该函数的含义为:如果字符串b在字符串a的里面,则返回的是b在a中的位置,即返回值大于0.
3、需要用到分组查询
4、使用wm_concat(cols)函数对学生姓名用逗号进行拼接.
解法:
select ci_id,wm_concat(stu_name) stu_name from (select ci_id,stu_name from pm_ci c,pm_stu s where instr(c.stu_ids,s.stu_id)>0) t group by ci_id;
Oracle学习笔记(八)的更多相关文章
- Oracle学习笔记八 表空间
表空间 表空间是一个或多个数据文件的集合,所有的数据对象都存放在指定的表空间中,但主要存放的是表, 所以称作表空间 . 分区表 当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下 ...
- Oracle学习笔记三 SQL命令
SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)
- Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...
- oracle学习笔记第一天
oracle学习笔记第一天 --oracle学习的第一天 --一.几个基础的关键字 1.select select (挑选) 挑选出显示的--列--(可以多列,用“,”隔开,*表示所有列),为一条 ...
- python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑
python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件?当我们点开下载页时, 一般 ...
- Go语言学习笔记八: 数组
Go语言学习笔记八: 数组 数组地球人都知道.所以只说说Go语言的特殊(奇葩)写法. 我一直在想一个人参与了两种语言的设计,但是最后两种语言的语法差异这么大.这是自己否定自己么,为什么不与之前统一一下 ...
- Oracle学习笔记——点滴汇总
Oracle学习笔记——点滴汇总 http://www.botangdb.com/ Oracle GI = Grid Infrastructure = ASM + Cluster
- Oracle学习笔记之四sp1,Oracle 11g的常用函数
从Oracle学习笔记之四,SQL语言入门中摘出来的,独立成一章节 3.1 字符类函数 ASCII(c)和CHR(i) 分别用于返回一个字符的ASCII码和返回给定ASCII值所对应的字符. C ...
- Oracle学习笔记之四,SQL语言入门
1. SQL语言概述 1.1 SQL语言特点 集合性,SQL可以的高层的数据结构上进行工作,工作时不是单条地处理记录,而对数据进行成组的处理. 统一性,操作任务主要包括:查询数据:插入.修改和删除数据 ...
随机推荐
- Linux常用命令总结--不断补充
首先介绍一个很有用的命令:history 查看linux机器上历史命令. 在Linux下查看内存我们一般用free命令:free -m 查看硬盘状况:df -h 查看cpu信息:less /proc ...
- 安装memcached服务 和 php 安装memcache扩展
这是所有的命令,至于哪个命令是干嘛的自己悟去吧 ,顺便穿插一些知识点 安装libevent cd /home/ wget http://www.monkey.org/~provos/libeven ...
- Java里的集合--主要区别
Collection 集合接口,指的是 java.util.Collection接口,是 Set.List 和 Queue 接口的超类接口. List: List是关注事物索引的列表. List中可以 ...
- Fedora安装vim失败解决方法
今天安装在fedora上安装vim的时候,出现如下错误 ================================================================= Downlo ...
- oracle 11g RAC 的一些基本概念(四)
RAC 在Grid Infrastructure安装完以后,我们把注意力转移到集群上的Oracle软件的安装上来.我们看到,Grid Infrasctructure提供了运行RAC的框架,包括集群 ...
- Solr Facet 统计查询
一)概述 Facet是solr的高级搜索功能之一,可以给用户提供更友好的搜索体验.在搜索关键字的同时,能够按照Facet的字段进行分组并统计.例如下图所示,你上淘宝,输入“电脑”进行搜索,就会出现品牌 ...
- 深入浅出 Java Concurrency (6): 锁机制 part 1 Lock与ReentrantLock
前面的章节主要谈谈原子操作,至于与原子操作一些相关的问题或者说陷阱就放到最后的总结篇来整体说明.从这一章开始花少量的篇幅谈谈锁机制. 上一个章节中谈到了锁机制,并且针对于原子操作谈了一些相关的概念 ...
- Hyberledger-Fabric 1.00 RPC学习(2)尝试建立一个network
本文参考:http://hyperledger-fabric.readthedocs.io/en/latest/build_network.html 这里我们学习建立第一个Hyperledger Fa ...
- 机器视觉和Tesseract
机器视觉 从 Google 的无人驾驶汽车到可以识别假钞的自动售卖机,机器视觉一直都是一个应用广 泛且具有深远的影响和雄伟的愿景的领域. 我们将重点介绍机器视觉的一个分支:文字识别,介绍如何用一些 P ...
- MultipartFile 转换为File
选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 . MultipartFile multipartFile; File fil ...