Mysql--連接查詢和子查詢

連接查詢和子查詢

一、連接查詢

1.1 概念

連接查詢:也可以叫跨表查詢,需要關聯多個表進行查詢

1.2 根據年代分類

SQL92:1992
SQL99:1999,更新的語法,主要掌握這種

DBA:DataBase Administrator【數據庫管理員】
老的DBA可能還在編寫SQL92語法。

1.3 根據連接方式分類

內連接:等值連接
       非等值連接
       自連接

外連接:左外連接(左連接)
       右外連接(右連接)

全連接

1.4 多表的連接查詢

所有涉及到的表:

員工表:

員工表.PNG

部門表:

部門表.PNG

薪水等級表:

薪水等級表.PNG
1.4.1 內連接中的等值連接

注意:在進行多表連接查詢的時候,盡量給表起別名,這樣效率高,可讀性高。

select e.ename,d.dname from emp e,dept d;
但不能使用as

若兩張表進行連接查詢的時候沒有任何條件限制,最終的查詢總數是兩張表記錄條數的乘積,這種現象被稱為笛卡爾積現象。為了避免笛卡爾積現象的發生,必須在進行表連接的時候添加限制條件

例一:查詢每一個員工所在的部門名稱,要求最終顯示員工和對應的部門名

SQL92語法:內連接中的等值連接
select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;

SQL99語法:內連接中的等值連接
select e.ename,d.dname from emp e join dept d on e.deptno = d.deptno;

SQL99語法的優點:

表連接獨立出來了,結構更清晰。對表連接不滿意的話,可以再追加where進行過濾。
select e.ename,d.dname from emp e inner join dept d on e.deptno=d.deptno;

select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;//inner可以省略

注意:在連接查詢的時候雖然使用了限制條件,但是匹配的次數沒有減少,還是56次,只不過這一次的結果都是有效記錄

1.4.2 內連接中的非等值連接

例二:找出每一個員工對應的工資等級,要求顯示員工名,工資,工資等級

員工薪水.PNG
SQL92語法:內連接中的非等值連接
select e.ename,e.sal,s.grade from emp e,salgrade s 
where e.sal between s.losal and s.hisal;

SQL99語法:內連接中的非等值連接(inner可以省略)
select e.ename,e.sal,s.grade from emp e (inner)join salgrade s 
on e.sal between s.losal and s.hisal;
1.4.3 內連接中的自連接

例三:找出每一個員工的上級領導,要求顯示員工名以及對應的領導名

例三.PNG
SQL92語法:內連接中的自連接
select a.ename empname,b.ename leadername from 
emp a ,emp b where a.mgr=b.empno;


SQL99語法:內連接中的自連接
select a.ename empname,b.ename leadername from 
emp a (inner)join emp b on a.mgr=b.empno;
1.4.4 外連接
內連接:查詢出A表和B表能夠完全匹配的記錄
外連接:查詢出A表和B表能夠完全匹配的記錄之外,
       將其中一張表的記錄無條件的完全查詢出來,對方表沒有匹配的記錄,
       會自動模擬出null與之匹配。

左外:把join關鍵字左邊的表數據全部顯示
右外:把join關鍵字右邊的表數據全部顯示

外連接的查詢結果條數>=內連接的查詢結果條數

例四:找出每一個員工對應的部門名稱,要求部門名全部顯示

SQL99語法:
外連接中的右外連接(右連接)(outer可以省略)
select e.ename,d.dname from emp e right (outer) join 
dept d on e.deptno=d.deptno;

外連接中的左外連接(左連接)(outer可以省略)
select e.ename,d.dname from dept d left (outer)join 
emp e on e.deptno=d.deptno;

注意:任何一個右外連接都可以寫成左外連接,任何一個左外連接也同樣可以寫成右外連接

為什么inner和outer可以省略,加上去有什么好處?

可以省略,因為區分內連接和外連接依靠的不是這些關鍵字,
而是看SQL語句中是否存在left/right;
若存在,表示一定是一個外連接,其他都是內連接
加上去的好處是增強可讀性。

例五:找出每一個員工對應的領導名,要求顯示所有的員工:

select a.ename empname,b.ename leadername from 
emp a left join emp b on a.mgr=b.empno;

例六:找出每一個員工對應的部門名稱,以及該員工對應的工資等級。
要求顯示員工名、部門名、工資等級

多表進行表連接的語法格式:

select xxx from a join b on 條件 join c on 條件;
原理:a表和b表連接之后,a表再和c表連接
例六.PNG
例六2.PNG
select e.ename,d.dname,s.grade from emp e
join dept d on e.deptno=d.deptno join
salgrade s on e.sal between s.losal and s.hisal;

二、子查詢

子查詢就是select語句嵌套select語句,可以理解為子查詢是一張表

2.1 在where語句中使用子查詢

找出薪水比公司平均薪水高的員工,要求顯示員工名和薪水

select ename,sal from emp where sal>avg(sal);
報錯!分組函數不能直接使用在where后面

第一步:找出公司的平均薪水
select avg(sal) from emp; 

第二步:找出薪水大于平均薪水的員工信息
select ename,sal from emp where sal>2073.214286;

即:select ename,sal from emp where sal>(select avg(sal) form emp);

2.2 在from語句中使用子查詢(將查詢結果當做臨時表)

找出每個部門的平均薪水,并且要求顯示平均薪水的薪水等級

第一步:找出每個部門的平均薪水
select deptno,avg(sal) as avgsal from emp group by deptno;

第二步:將上面的查詢結果當做臨時表t,t表和salgrade s表進行表連接,
條件:t.avgsal between s.losal and s.hisal

即:
select t.deptno,t.avgsal,s.grade
from (select deptno,avg(sal) as avgsal from emp group by deptno) t
join salgrade s
on t.avgsal between s.losal and s.hisal;

2.3 在select語句中使用子查詢

select e.ename,(select d.dname from dept d where e.deptno=d.deptno)
as dname from emp e;

三、union和limit

3.1 union

作用:合并查詢結果集

找出工作崗位是salesman和manager的員工

select ename,job from emp where 
job='manager' or job='salesman';

或:select ename,job from emp where
job in('manager','salesman');

使用union:
select ename,job from emp where job='manager'
union
select ename,job from emp where job='salesman';

注意:使用union,要求兩個select的字段數量相同,類型可以不同,但在oracle中,類型也要求相同。

例:

select ename as enamedname from emp
union
select dname as enamedname from dept;

3.2 limit

  • 1.limit用來獲取一張表中的某部分數據
  • 2.limit只有在mysql數據庫中存在,不通用,是mysql數據庫管理系統的特色。

例:找出員工表中前5條記錄

select ename from emp limit 5;

以上sql語句的limit中的5表示從表中記錄下標0開始,取5條
等同于下面的sql語句:

select ename from emp limit 0,5;

limit的語法:

limit 起始下標,長度
如果起始下標沒有指定,默認從0開始,0表示表中第一條記錄。

例:找出公司中工資排名在前5名的員工(limit出現在sql語句的最后位置上)

思路:按照工資降序排列取前5個
select ename,sal from emp order by sal desc limit 5;

例:找出工資排名在3-9名的員工

select ename,sal from emp order by sal desc limit 2,7;
MySql中通用的分頁sql語句:
每頁顯示3條記錄
第1頁:0,3
第2頁:3,3
第3頁:6,3
第4頁:9,3
...

每頁顯示pageSize條記錄
第pageSize頁:(pageNo-1)*pageSize,pageSize

通用的分頁SQL(只適用于mysql數據庫管理系統)

select t.* from t
order by t.x desc/asc
limit (pageNo-1)*pageSize,pageSize;

計算共有多少頁:
pageCount = (totalCount + count - 1)/count ;
pageCount:共有多少頁
totalCount:總共多少條數據
count:每頁顯示多少條數據

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容