select dname from dept d wherenotexists (selectnull from emp e where e.deptno = d.deptno and comm isnotnull ) ;
第 5 行 where 條件句中主查詢(MasterQuery)與子查詢(SubQuery)有了相關性,所以稱為 Correlated Subquery。碰到 NOT 這種反向邏輯總是會腦袋變殘,要好好思考。這種 Correlated Subquery 是最基礎與通常的寫法。結果如下。
Result
DNAME -------------- 開發部 RESEARCH 會計部
不相關性子查詢 Uncorrelated Subquery
Uncorrelated Subquery
1 2 3 4 5 6 7
select dname from dept where deptno notin (select deptno from emp where comm isnotnull ) ;
主查詢與子查詢沒有直接的相關性,這稱為 Uncorrelated Subquery。
答案一樣這裡就不列出,不要直接複製貼上只看解答,瞄它一眼,然後自己寫寫看。
使用 NOT IN 時,小心 Null 值,我們先不要中斷這裡的思考,留待後面再來談這個 Nulls 的問題。
Outer Join
Outer Join
1 2 3 4 5 6 7
select dname from dept d leftouterjoin emp e on e.deptno = d.deptno and e.comm isnotnull where e.deptno isnull ;
集合函数 Aggregate functions
Aggregate function,平常用的最多的就是 count( ), 你如果以為 Aggregate function 不外乎只有,SUM、AVG、MAX、MIN 的功能,那可能就太小看它了。注意,這些集合函數總是與 Group by 同時出現。
SUM
Aggregate function SUM
1 2 3 4 5 6 7 8 9 10 11 12
select dname from (select dname, casewhen comm isnullthen0 else1 endas flag from emp e, dept d where e.deptno (+) = d.deptno ) s groupby dname havingsum(flag) = 0 ;
這與上段類似,但直接省掉 Inline View。
Aggregate function SUM without Inline View
1 2 3 4 5 6 7 8 9
select dname from emp e, dept d where e.deptno (+) = d.deptno groupby dname havingsum(casewhen e.comm isnullthen0 else1 end) = 0 ;
MAX
Aggregate function MAX
1 2 3 4 5 6 7
select dname from emp e, dept d where e.deptno (+) = d.deptno groupby dname havingmax(coalesce(e.comm,0)) = 0 ;
集合 Set Operation
Set Operation
1 2 3 4 5 6 7 8 9
select dname from dept MINUS select dname from dept d, emp e where d.deptno = e.deptno and e.comm isnotnull ;
Subquery Factoring
Subquery Factoring
1 2 3 4 5 6 7 8 9 10 11 12 13 14
with x as ( select dname, casewhen comm isnullthen0 else1 endas flag from emp e, dept d where e.deptno (+) = d.deptno ) select dname from x groupby dname havingsum(flag) = 0 ;
Analytic function
Analytic function
1 2 3 4 5 6 7 8 9 10 11
with x as ( select deptno, sum(coalesce(comm, 0)) over(partitionby deptno) dept_comm from emp ) selectdistinct dname from x, dept d where x.deptno (+) = d.deptno andcoalesce(dept_comm, 0) = 0 ;