資料庫:mysql基礎(四)---高階查詢
阿新 • • 發佈:2018-12-15
子查詢(巢狀查詢)
-
將一個查詢結果作為另一個查詢的條件或者組成繼續進行檢索
-
分類
-
#先看一個例子 #查詢20號部門所有員工及其所在部門資訊 #用關聯查詢來做 select * from emp,dept where emp.deptno = dept.deptno and emp.deptno = 20; #用子查詢來做 #先找出來20號部門員工的資訊 select * from emp where deptno =20; #from子句是可以跟表,結果集的,所以我們可以按下面這樣 select * from (select * from emp where deptno =20) e,dept where e.deptno = dept.deptno; #再看下面一個例子 #查詢所有員工及其上級領導(mgr)的名稱(自連線) select e1.ename '姓名',e2.ename '領導' from emp e1 left join emp e2 on e1.mgr = e2.empno; #繼續看下面這個例子 #查詢編號為7788的員工所在部門的資訊。是否發現什麼不同 #我們要查詢的結果在一張表內,但是查詢的條件卻在另外一張. 當然我們用關聯查詢也能做出來 select dept.* from (select * from emp where empno = 7788) e,dept where e.deptno = dept.deptno; #除了上面這種思路還有其他的麼?其實有一個更為直接的思考方式 #查詢7788員工的部門編號 select deptno from emp where empno =7788; #結果是20 #根據部門編號查詢部門資訊 select * from dept where deptno = 20; #我們結合一下 select * from dept where deptno = (select deptno from emp where empno =7788); #這種思路,就是找到這些表的關聯欄位.只要我們知道關聯欄位,我們就能查詢了--將條件和結果放到一張表中(查詢通用列)
其實巢狀查詢就比較符合我們思考方式的一種查詢了.
-
單行子查詢---子查詢返回結果是一條記錄
-
select * from dept where deptno = (select deptno from emp where empno =7788);返回的就是一條記錄,部門編號
-
-
多行子查詢:子查詢返回多條記錄
-
#查詢工資大於2000的員工所在部門資訊。
-
select * from dept where deptno in (select distinct deptno from emp where sal > 2000);
-
-
除了in 我們還可以用 any / all
-
=any: 相當於in >any:大於最小值 <any:小於最大值
-
>all:大於最大值 <all:小於最小值
-
-
下面是一些小的練習..可以思考一下
-
-
#查詢工資>20號部門平均工資的員工資訊。 #子查詢:先找出來20號部門的平均工資 select avg(sal) from emp where deptno = 20 select * from emp where sal > (select avg(sal) from emp where deptno = 20); #查詢工資>20號部門平均工資並且不在20號部門的員工資訊。 select * from emp where sal > (select avg(sal) from emp w here deptno = 20) and deptno <> 20; #查詢工資大於所在部門的平均工資的員工資訊。 #方式1,關聯查詢 select emp.* from emp,(select deptno,avg(sal) avg from emp group by deptno) e where emp.deptno = e.deptno and sal > e.avg; #方式2:巢狀查詢 select * from emp e1 where sal > (select avg(sal) from emp e2 where e2.deptno = e1.deptno); #最後一題用巢狀方式查詢的執行過程: #主查詢將deptno傳給子查詢 #子查詢根據主查詢的deptno查詢指定部門的平均工資 #子查詢將該部門平均工資返回給主查詢 #主查詢根據返回結果進行最後檢索。
-
下面看一下前面做過的題
-
#查詢20號部門以及工資>2000的員工資訊。 select * from dept where deptno in (select deptno from emp where sal > 2000); #上面的一個細節:就是主查詢要的是一個deptno,所以子查詢就要返回一個deptno #如果子查詢返回的是deptno,dname的話,那麼就會報錯了.如果子查詢返回的結果不是一個,但是主查詢所需條件只能一個,那怎麼做呢? #有沒有這樣一種方式,我們不關心子查詢返回了多少個結果,而只是去想辦法讓主查詢中的條件能在子查詢返回的結果中找到呢?引出了下面的關鍵字 exists. #exists 就是不關心子查詢你到底返回了多少個欄位,只是關心你返回的所有欄位中有沒有我需要的欄位. #下面說一下這道題應用exists的解法 select * from dept where exists (select * from emp where sal > 2000 and emp.deptno = dept.deptno);
-
in和exists的區別
- in先執行子查詢,將查詢得到的結果整理完畢返回給主查詢,主查詢再根據條件在子查詢返回的結果中查詢,exists先執行主查詢,把值交給子查詢,依次去匹配
- in需要關注子查詢返回值的欄位資訊;exists不需要關係返回欄位
- exsts將主查詢的記錄依次在子查詢匹配,如果匹配返回true並展示
-
-
那麼我們什麼時候用關聯查詢,什麼時候使用子查詢呢?
- 如果我們查詢的結果存在於多張表的時候,使用關聯查詢較好
- 如果結果分佈在一張表的時候,子查詢較好
- 效率上的差異:關聯查詢是將多張表關聯在一起,資源佔用上稍微高一點;子查詢資源的消耗稍微小一點,但是它可能存在多次查詢