oracle--子查询和集合运算

子查询和集合运算

一、子查询

语法:

select select_list 
from table 
where expr operator
            (select select_list from table);

子查询(内查询)在主查询之前一次执行完成。
子查询的结果被主查询使用(外查询)。

注意:

子查询要包含在括号内。
将子查询放在条件的右侧。
单行操作符对应单行子查询,多行操作符对应多行子查询。

例:

SQL> --查询工资比SCOTT高的员工信息
SQL> --1. SCOTT的工资
SQL> select sal from emp where ename='SCOTT';

       SAL                                                                      
----------                                                                      
      3000                                                                      

SQL> --2. 比3000高的员工
SQL> set linesize 200
SQL> select * from emp where sal > 3000;

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO                                                                                                              
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------                                                                                                              
      7839 KING       PRESIDENT            17-11月-81           5000                    10                                                                                                              

SQL> --子查询所要解决的问题: 不能一步求解
SQL> select *
  2  from emp
  3  where sal > (select sal
  4               from emp
  5               where ename='SCOTT');

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO                                                                                                              
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------                                                                                                              
      7839 KING       PRESIDENT            17-11月-81           5000                    10           

注意的问题:

1. 括号
2. 合理的书写风格
3. 可以在where select having from后面 都可以使用子查询
4. 不可以在group by后面使用子查询
5. 强调from后面的子查询
6. 主查询和子查询可以不是同一张表;只要子查询返回的结果 主查询可以使用 即可
7. 一般不在子查询中排序;但在top-n分析问题中,必须对子查询排序
8. 一般先执行子查询,再执行主查询;但相关子查询例外
9. 单行子查询只能使用单行操作符;多行子查询只能使用多行操作符
    单行子查询:只返回一行,使用单行比较操作符
    多行子查询:返回多行,使用多行比较操作符
10.子查询中的null

3.可以在where select having from后面 都可以使用子查询:

SQL> select empno,ename,sal,(select job from emp where empno=7839) 第四列
  2  from emp;

5.强调from后面的子查询

SQL> --查询员工信息:员工号  姓名 月薪
SQL> select *
  2  from (select empno,ename,sal from emp);

--查询员工信息:员工号  姓名 月薪 年薪
select * from (select empno,ename,sal,sal*12 annsal from emp)

思考:

select empno,ename,sal,sal*12 annsal from emp;
select * from (select empno,ename,sal,sal*12 annsal from emp);
以上两条语句性能一样

6.主查询和子查询可以不是同一张表;只要子查询返回的结果 主查询可以使用即可

查询部门名称是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';

SQL 优化:尽量使用多表查询

单行比较操作符:

单行比较操作符.PNG

执行单行子查询:

select ename,job,sal from emp
where job = 
         (select job from emp where empno = 7566)
and sal > 
         (select sal from emp where empno = 7782);

在子查询中使用组函数
select ename,job,sal from emp where sal = 
                                      (select min(sal)
                                       from emp);

子查询中的having子句

首先执行子查询
向主查询中的having子句返回结果
select deptno,min(sal) 
from emp
group by deptno
having min(sal) > 
                 (select min(sal)
                  from emp
                  where deptno = 10);

多行比较操作符

多行比较操作符.PNG
SQL> --in 在集合中
SQL> --查询部门名称是SALES和ACCOUNTING的员工
SQL> select *
  2  from emp
  3  where deptno in (select deptno from dept where dname='SALES' or dname='ACCOUNTING');

SQL> --any: 和集合中的任意一个值比较
SQL> --查询工资比30号部门任意一个员工高的员工信息
SQL> select *
  2  from emp
  3  where sal > any (select sal from emp where deptno=30);
等价于:
select * from emp where sal > (select min(sal) from emp where deptno=30)

SQL> --all 和集合中的所有值比较
SQL>  --查询工资比30号部门所有员工高的员工信息
SQL> select *
  2  from emp
  3  where sal > all (select sal from emp where deptno=30);
等价于:
select * from emp where sal > (select max(sal) from emp where deptno=30)

多行子查询中的null:

SQL> --not in (10,20,null)
SQL> --查询不是老板的员工

SQL> --查询是老板的员工
SQL> select *
  2  from emp
  3  where empno in (select mgr from emp);

SQL> select *
  2  from emp
  3  where empno not in (select mgr from emp where mgr is not null);

二、集合运算

集合运算符:

集合运算符.PNG
union:返回两个集合去掉重复元素后的所有记录
union all:返回两个集合的所有记录,包括重复的
intersect:运算符返回同时属于两个集合的记录
minus:返回属于第一个集合,但不属于第二个集合的记录

例:

SQL> /*
SQL> 查询10和20号部门的员工
SQL> 1. select * from emp where deptno in (10,20);
SQL> 2. select * from emp where deptno=10 or deptno=20;
SQL> 3. 集合运算
SQL>    select * from emp where deptno=10
SQL>      加上
SQL>    select * from emp where deptno=20
SQL> */
SQL> select * from emp where deptno=10
  2  union
  3  select * from emp where deptno=20;

SQL> select deptno,job,sum(sal) from emp group by rollup(deptno,job);

注意的问题:

select语句中的参数类型和个数要一致
可以使用括号改变集合执行的顺序
如果有order by子句,必须放到最后一句查询语句后
集合运算采用第一个语句的表头作为表头

SQL>  select deptno,job,sum(sal) from emp group by deptno,job
  2   union
  3   select deptno,to_char(null),sum(sal) from emp
  4   union
  5   select to_number(null),to_char(null),sum(sal) from emp;

SQL 优化 5. 尽量不要使用集合运算

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容