08.多表查詢下篇

四、子查詢

一個select語句中包含另一個完整的select語句。
子查詢就是嵌套查詢,即SELECT中包含SELECT,如果一條語句中存在兩個,或兩個以上SELECT,那麼就是子查詢語句了。
子查詢出現的位置:

  • where後,作爲條爲被查詢的一條件的一部分;
  • from後,作表;

當子查詢出現在where後作爲條件時,還可以使用如下關鍵字:

  • any
  • all

子查詢結果集的形式:

  • 單行單列(用於條件)
  • 單行多列(用於條件)
  • 多行單列(用於條件)
  • 多行多列(用於表)

練習:
1.工資高於JONES的員工。
分析:
查詢條件:工資>JONES工資,其中JONES工資需要一條子查詢。

第一步:查詢JONES的工資

SELECT sal FROM emp WHERE ename='JONES'

這裏寫圖片描述

第二步:查詢高於JONES工資的員工

SELECT * FROM emp WHERE sal > (${第一步})

結果:

SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE ename='JONES')

這裏寫圖片描述

2、查詢與SCOTT同一個部門的員工。

第一步:查詢scott的部門

SELECT deptno FROM emp WHERE ename="scott";

這裏寫圖片描述
第二步:查詢與SCOTT同一個部門的員工

SELECT * FROM emp WHERE deptno=(${第一步});

結果:

SELECT * FROM emp WHERE deptno=(SELECT deptno FROM emp WHERE ename="scott");

這裏寫圖片描述
- 子查詢作爲條件
- 子查詢形式爲單行單列

3、工資高於30號部門所有人的員工信息
分析:

SELECT * FROM emp WHERE sal>(SELECT MAX(sal) FROM emp WHERE deptno=30);

查詢條件:工資高於30部門所有人工資,其中30部門所有人工資是子查詢。高於所有需要使用all關鍵字。

第一步:查詢30部門所有人工資

SELECT sal FROM emp WHERE deptno=30;

這裏寫圖片描述
第二步:查詢高於30部門所有人工資的員工信息

SELECT * FROM emp WHERE sal > ALL (${第一步})

結果:

SELECT * FROM emp WHERE sal > ALL (SELECT sal FROM emp WHERE deptno=30)

這裏寫圖片描述
- 子查詢作爲條件
- 子查詢形式爲多行單列(當子查詢結果集形式爲多行單列時可以使用ALL或ANY關鍵字)

4、查詢工作和工資與MARTIN(馬丁)完全相同的員工信息
分析:
查詢條件:工作和工資與MARTIN完全相同,這是子查詢

第一步:查詢出MARTIN的工作和工資

SELECT job,sal FROM emp WHERE ename='MARTIN'

這裏寫圖片描述

第二步:查詢出與MARTIN工作和工資相同的人

SELECT * FROM emp WHERE (job,sal) IN (${第一步})

結果:

SELECT * FROM emp WHERE (job,sal) IN (SELECT job,sal FROM emp WHERE ename='MARTIN')

這裏寫圖片描述
5、有2個以上直接下屬的員工信息

第一步:查詢出有2個以上直接下屬的員工編號

SELECT mgr FROM emp GROUP BY mgr HAVING COUNT(mgr)>=2

這裏寫圖片描述
第二步:根據員工編號查詢出其他信息

SELECT * FROM emp WHERE empno IN (${第一步});

結果:

    SELECT * FROM emp WHERE empno IN(SELECT mgr FROM emp GROUP BY mgr HAVING COUNT(mgr)>=2);

這裏寫圖片描述
- 子查詢作爲條件
- 子查詢形式爲單行多列

5、查詢員工編號爲7788的員工名稱、員工工資、部門名稱、部門地址

分析:(無需子查詢)
查詢列:員工名稱、員工工資、部門名稱、部門地址
查詢表:emp和dept,分析得出,不需要外連接(外連接的特性:某一行(或某些行)記錄上會出現一半有值,一半爲NULL值)
條件:員工編號爲7788

第一步:去除多表,只查一張表,這裏去除部門表,只查員工表

SELECT ename, sal FROM emp e WHERE empno=7788

這裏寫圖片描述
第二步:讓第一步與dept做內連接查詢,添加主外鍵條件去除無用笛卡爾積

SELECT e.ename, e.sal, d.dname, d.loc 
FROM emp e, dept d 
WHERE e.deptno=d.deptno AND empno=7788

這裏寫圖片描述
第二步中的dept表表示所有行所有列的一張完整的表,這裏可以把dept替換成所有行,但只有dname和loc列的表,這需要子查詢。

第三步:查詢dept表中dname和loc兩列,因爲deptno會被作爲條件,用來去除無用笛卡爾積,所以需要查詢它。

SELECT dname,loc,deptno FROM dept;

第四步:替換第二步中的dept

SELECT e.ename, e.sal, d.dname, d.loc 
FROM emp e, (SELECT dname,loc,deptno FROM dept) d 
WHERE e.deptno=d.deptno AND e.empno=7788
  • 子查詢作爲表
  • 子查詢形式爲多行多列
    這裏寫圖片描述

6、自連接:自己連接自己,起別名,把自己看成多張表
求7369員工編號、姓名、經理編號和經理姓名

SELECT e1.empno , e1.ename,e2.empno AS mgrno,e2.ename 
FROM emp e1, emp e2 
WHERE e1.mgr = e2.empno AND e1.empno = 7369;

這裏寫圖片描述

練習:
求各個部門薪水最高的員工所有信息

    select e.* from emp e,

(select max(sal) maxsal,deptno from emp
group by deptno) a
where e.deptno = a.deptno
and e.sal =a.maxsal
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章