原標題:《MySQL數據庫》關聯查詢
一、關聯查詢
1、概念
在查詢數據時,所需要的數據不只在一張表中,可能在兩張或多張表中。這個時候,需要同時操作這些表來查詢數據,即關聯查詢。
關聯查詢所涉及到的表與表之間都會存在有關聯的字段,如員工表的部門編號和部門表的部門編號。
2、笛卡爾積
在做關聯查詢時,數據庫會使用某一張表中的每一條記錄都與另外一張表的所有記錄進行組合。比如表A有x條記錄,表B有y條記錄,最終組合數為x*y,這個值就是笛卡爾積,通常沒有意義。
3、等值連接
在做關聯查詢時,這些表中存在著有關聯的兩個字段。我們使用某一張表中的一條記錄通過相關聯的字段與另外一張表的記錄進行匹配,組合成一條新的記錄。使用"="連接關聯字段
需求1:查詢員工的姓名,職位及其所在部門的名稱 、地址
4、內連接
內連接返回所有滿足條件的記錄,關鍵字join on。查詢效果與等值連接一樣。用法:表A [inner] join 表B on 關聯條件
5、外連接
在做關聯查詢時,我們所需要的數據,除了那些滿足關聯條件的數據外,還有不滿足關聯條件的數據。此時需要使用外連接。
會涉及到兩個概念:
驅動表(主表):除了顯示滿足條件的數據,還需要顯示不滿足條件的數據的表
從表(副表):只顯示滿足關聯條件的數據的表
mysql外連接只支持左外連接,右外連接,不支持全外連接
左外連接:
表A left [outer] join 表B on 關聯條件。
表A是驅動表,表B是從表
右外連接
表A right [outer] join 表B on 關聯條件
表B是驅動表,表A是從表
全外連接:
兩張表的數據不管滿不滿足條件,都做顯示。
表A full [outer] join 表B on 關聯條件
PS:mysql 不支持全外連接
需求1:查詢所有員工的姓名,職位,及其部門編號,部門名稱----分析:員工表為驅動表,部門表為從表
select e.ename,e.job,e.deptno,d.dname from emp e left join dept d on e.deptno = d.deptno;
6、自連接
自連接是一種特殊的關聯查詢。數據的來源是同一個表,這樣的表內的多個字段要存有關系。我們要使用表別名來虛擬出兩個表。
需求1:查詢員工姓名,職位及其上司姓名,職位。
mysql > select a.ename 員工姓名,
a.job 員工職位,
b.ename 上司姓名,
b.job 上司職位
from emp a join emp b on a.mgr=b.empno;
分析:可以看出 a的mgr與b的empno關聯,所以,a是員工表,b是領導表
二、高級關聯查詢
有的時候,我們要查詢的數據,一個簡單的查詢語句完成不了,并且我們使用的數據,表中不能直觀體現出來。而是預先經過一次查詢才會有所體現。那么先執行的查詢,我們稱之子查詢。被子查詢嵌入的查詢語句稱之為父查詢或主查詢。
主查詢可以是select語句,也可以是DML語句或者是DDL語句。
根據子查詢返回結果的不同,可以分為單行單列子查詢、多行單列子查詢、多行多列子查詢。
子查詢所在的位置,有可能出現在以下地方:
1)子查詢可以在where子句中
2)子查詢可以在from子句中
3)子查詢可以在having子句中
4)子查詢可以在select字句中,相當于外連接的另外一種寫法。
1、在where子句中
需求1:查詢和員工姓名scott同職位的員工信息。
select ename,job,hiredate,sal,deptno from emp where job=(select job from emp where ename='scott');
需求2:查詢薪水比所有員工的平均薪水高的員工信息
mysql > select ename,job,hiredate,sal from emp where sal > (select avg(ifnull(sal,0)) from emp);
需求3:查詢出部門中有salesman但是職位不是salesman的員工信息
select ename,job,hiredate,sal,deptno from emp where deptno in (select distinct deptno from emp where job='salesman') and job <> 'salesman';
exists 關鍵字
有時候,子查詢需要引用主查詢的字段數據,我們使用exists關鍵字。exists后面的子查詢至少返回一條記錄,則整個條件為true;
需求:查詢有員工的部門信息
mysql > select deptno,dname,loc from dept d where exists (select * from emp e where d.deptno =e.deptno);
2、在from子句中
from子句用于指定表,如果想在一個子查詢的結果里繼續查詢,則子查詢需要寫在from子句中,相當于一個表。
需求1:查詢工資大于本部門平均工資的員工的信息。
mysql > select e.ename,e.sal,t.avg_sal,t.deptno from emp e join (select deptno,avg(ifnull(sal,0)) 'avg_sal' from emp group by deptno) t on e.deptno = t.deptno and e.sal>t.avg_sal order by t.deptno;
需求2:查詢每個員工的工資,姓名和其部門的平均工資。
select e.ename, e.sal, t.avg_sal from emp e , (select deptno,avg(ifnull(sal,0)) 'avg_sal' from emp group by deptno) t where e.deptno = t.deptno order by t.deptno;
3、在having子句中
需求:查詢平均工資大于30號部門平均工資的部門號、平均工資
mysql > select deptno,avg(ifnull(sal,0)) from emp group by deptno having avg(ifnull(sal,0))>(select avg(ifnull(sal,0)) from emp where deptno=30);
4、在select子句中
需求1:查詢每個員工的姓名,工資,及其部門的平均工資,工資之和
select ename,sal,
(select avg(ifnull(sal,0)) from emp a where a.deptno=b.deptno) avg_sal ,
(select sum(sal) from emp c where c.deptno=b.deptno ) sum_sal
from emp b order by b.deptno;返回搜狐,查看更多
責任編輯: