MySQL筆記三:DQL(2)——連線查詢、笛卡爾積、union和limit
阿新 • • 發佈:2022-04-09
3.1連線查詢的概念
從一張表單獨查詢稱為單表查詢,多張表聯合起來查詢資料,被稱為連線
根據表連線的方式分類:
內連線:等值連線、非等值連線、自連線
外連線:左外連線(左連線)、右外連線(右連線)
全連線(較少用到)
3.2笛卡爾積現象
兩張表連線沒有限制,則總資料數時兩張表條數的乘積,稱為笛卡爾積現象
表的連線次數越多,連線效率越低,所以要儘量避免表的連線
select ename,dname from emp,dept;//一共n1*n2條資料
避免笛卡爾積現象:連線時加上條件
select ename,dname from emp,dept where emp.deptno = dept.deptno;//一共n1條資料,匹配次數沒有減少,只不過在where處進行了篩選,SQL92,以後少用SQL92
select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno;//起別名,在select中加上對應的表,可以提升效率,很重要
3.3內連線——等值連線(連線條件為等值關係)
要求:查詢員工姓名、員工所在部門名稱
select e.ename,d.dname
from emp e
inner join dept d
on e.deptno = d.deptno;//SQL99,後續需要進一步篩選,可以在後面繼續新增where,結構比SQL92語法更清晰,inner可以省略,但是寫上可讀性更好
3.4內連線——非等值連線(連線條件不是一個等值關係)
要求:查詢員工姓名、薪資與薪資等級
select e.ename,e.sal,s.grade
from emp e
inner join salgrade s
on e.sal between s.losal and s.hisal;
3.5內連線——自連線(同一張表自己和自己連線)
要求:查詢員工的上級領導,要求顯示員工名和對應的領導名
技巧:一張表看成兩張表
select e.name as '員工’,m.name as '領導'
from emp e
join emp m
on e.mgr = m.empno;//如果出現null,則該條資料不顯示
3.6外連線
//右連線
select e.ename,d.dname
from emp e
right outer join dept d
on e.deptno = d.deptno;//right代表將join關鍵字右邊的表看成主表,主要是為了將右邊的表的資料全部查詢出來,捎帶查詢左邊的表,outer可以省略,加上可讀性更強一點
//左連線
select e.ename,d.dname
from emp e
right outer join dept d
on e.deptno = d.deptno;//leftt代表將join關鍵字左邊的表看成主表
外連線:兩張表產生了主次關係
內連線:將所有滿足連線條件的資料顯示出來,兩張表沒有主次關係,如果有null的資料,則該條資料就不顯示了
外連線的查詢結果一定大於內連線查詢結果
3.7三張表、四張表連線
select ...
from a
join b
on a和b連線的條件
join c
on a和c連線的條件
right join d
on a和d連線的條件
select e.ename,e.sal,d.dnane,s.grade
from emp e
join dept d
on e.deptno=d.deptno
join salgrade s
on a.sal between s.losal and s.hisal;
3.8子查詢
select語句中巢狀select語句,被巢狀的select語句被稱為子查詢
select
...(select)
from
...(select)
where
...(select);
例子1:要求找出比最低工資高的員工姓名和工資——where中的子查詢
技巧:先找出最低工資,然後找出大於最低工資的資料,最後合併
select ename,sal from emp where sal>(select min(sal) from emp);
例子2:找出每個崗位的平均工資的薪資等級——from中的子查詢
技巧:from後面的子查詢,可以將子查詢的結果作為一張臨時表
預備知識:先找出每個崗位的平均工資
select job,avg(sal)
from emp
group by job
解決方法:將查詢結果當成真實存在的表
select t.job,t.avgsal,s.grade
from (select job,avg(sal) as avgsal from emp group by job) t
join salgrade s
on t.avgsal between s.losal and s.hisal;//需要注意將avg(sal)起別名,不然會被當成關鍵字會報錯
例子3:找出每個員工的名字和部門名——select中的子查詢
注意:對於select後面的子查詢,這個子查詢只能返回一條結果,返回多餘一條則報錯
select
e.name,(select d.dname from dept d where e.deptno=d.deptno) as dname
from
emp e;
3.9union合併查詢結果
union的效率比連線的效率更高一點,union把乘法變成了加法
select ename,job from emp where job = 'MANAGER'
union
select ename,job from emp where job = 'SALESMAN';
注意:union進行查詢結果合併時,MySQL要求兩個結果的列數相同;oracle還要求合併時不僅列數相同,列的型別也要求相同
3.10limit取出部分查詢結果
limit將查詢結果的一部分取出來,通常用於分頁查詢中,例如百度一頁顯示10條內容,分頁的作用是提高使用者的體驗
limit startIndex,length;//完整用法:startIndex是起始下標,從0開始,length是長度
limit length;//預設用法:從0開始,取前length個
limit在order by之後執行,在排序之後再使用
例子:按照薪資降序,取前5名員工
select ename,sal
from emp
order by sal desc
limit 0,5;
分頁
每頁顯示pageSize條記錄,則第page頁的limit約束:limit (pageNum-1)*pageSize, pageSize;
綜合順序
select ...
from ...
where ...
order by ....
having ...
limit ...