mysql-6多表查詢(連表查詢、子查詢、limit分頁查詢)


6.多表查詢

a.連接查詢

1.連接查詢

  • 1.1多表連接,跨表查詢

  • 1.2分類:sql92,sql99

  • 1.3 表連接分類:

    • 內連接:等值連接、非等值連接、自連接,
    • 外連接:左外連接(左連接)、右外連接(右連接),
    • 全連接

2.笛卡爾積

當兩張表進行連接查詢,沒有任何條件限制的,最終查詢結果條數,是兩張表條數的乘積,這種現象被稱為:笛卡爾積

select ename,dname from emp,dept;
  • 1.5如何避免笛卡爾積現象 (sql92語法)

  • 雖然使用where 進行條件篩選,但是並沒有減少匹配此次

  • 表的連接次數越多,效率越低,盡量避免表的連接

  select ename,dname from emp,dept where emp.deptno=dept.deptno; 通過設定條件(sql92語法)
  
  -- 優化
  select emp.ename,dept.dname from emp,dept where emp.deptno=dept.deptno;
  
  -- 使用別名進行進一步優化,提供效率
  select e.ename,d.dname from emp e,dept d  where e.deptno= d.deptno;
  

3.內連接- 等值連接(條件是等量關系故稱等值連接) inner

案例:查詢每個員工所在部門名稱,顯示員工名和部門名

emp e 和dep d 表進行連接。條件是e.deptno = d.deptno

-- sql 92語法
select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno
-- sql 99語法 join 前inner 可省略
select 
	e.ename,d.dname 
from 
	emp e 
join 
	dept d 
on 
	e.deptno= d.deptno;

  • sql92缺點:結構不清晰,表的連接條件,和后期進一步篩選的條件,都放在where后面
  • sql99優點:表連接的條件是獨立的,連接之后,如果還需進一步篩選,再往后繼續添加where

4.內連接- 非等值連接

條件不是一個等量關系,稱為非等值連接

范圍、等級、取值區間關聯,使用between.. and..

-- between .. and 
select 
	e.ename,e.sal,s.grade
from
	emp e
join
	salgrade s
on 	
	e.sal between s.losal and s.hisal;

5.內連接 -自連接

技巧:把一張表,看成兩張表

對emp 領導表內進行自連接,需要把emp 表既看成員工表,也看成領導表

empno ename mgr
7369 smith 7902
7499 allen 7698
7698 blark 7839
7902 ford 7566
-- 
select 
	a.ename as '員工名', b.ename as'領導名'
from 
	emp a
join 
	emp b
on 
	a.mgr=b.empno;  
--  員工的領導編號 = 領導的員工編號

6.外連接

  • 右外連接 right join

    ​ 右表為主表,將右表全部查詢出來,捎帶關聯左邊的表

    ​ 在外鏈接當中,兩張表連接,產生了主次關系。

  • 左外連接亦然 left join

-- 右外連接
-- 可帶outer 帶上可讀性更強
select 
	e.ename,d.dname 
from 
	emp e 
right  outer join   
	dept d  -- 右邊全部匹配
on 
	e.deptno= d.deptno;

總結 外連接的查詢結果條數一定是>=內連接的查詢結果條數

7.三張表,四張表連接

-- 語法:
select 
 ... 
from 
	a
join 
	b
on 
	a和b的連接條件
join 
	c
on 
 	a和c的條件
join 
	d
on 
	a和d的條件
-- 一條sql中內連接和外連接可以混合,都可以出現

案例:

找出每個員工的部門名稱以及工資等級,要求顯示員工名、部門名、薪資、薪資等級

如果再加上查詢員工的上級領導(使用外連接,避免刪除)

分析:從emp 取出ename, 關聯dept,取dname, 關聯salgrade 取grade

emp
empno ename sal depton
7398 smith 800.00 20
7499 allen 1600.00 30
7521 ward 1250.00 30
7654 martin 1250.00 30
dept
deptno dname loc
10 accounting new york
20 research dallas
30 sales chicago
40 operations boston
salgrde
grade losal hisal
1 700 1200
2 1201 1400
3 1401 2000
4 2001 3000
select e.ename,d.dname,s.grade
from emp e 
join dept d 
on  e.depton = d.depton.deptno
join salgrade s
on  e.sal between s.losal and  s.hisal;

b.子查詢

1.子查詢

select 語句中嵌套select 語句,被嵌套的select 的語句稱為子查詢

2.where 條件后的子查詢

-- 子查詢1,where條件中
select 表頭a from 表a  where  表頭  ..   (select .. from table_b)

3.from 子語句中的子查詢 (可以將子查詢的結果當做一張臨時表)

-- from 子句中的子查詢
from 后面的子查詢,可以將子查詢的查詢結果當做一張臨時表。(技巧)

__注意__子查詢注意分組函數的使用時易被錯認為函數,導致報錯,需要對該分組函數命名

4.select 后面出現的子查詢

select 按表行搜索,類似循環嵌套,(使用聯表進行查詢)

  • select 后面出現的子查詢只能返回一條結果,多於一條報錯

    -- 實例
    理解: 查詢emp表,分別查詢e對應的ename列,deptno列,以及e第一行中對應的deptno 對應d表中的dname,
    select 
    	e.ename,e,deptno (select d.dname from dept d where e.deptno=d.deptno) as dname 
    from 
    	emp e;
    
  • 實例 查詢各科成績前三名的記錄:(不考慮成績並列情況)

select score.sid,score.course_id,score.num,T.first_num,T.second_num from score left join
 (select
        sid,
        (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 0,1) as first_num,
        (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 3,1) as second_num
    from
        score as s1
    ) as T
    on score.sid =T.sid
    where score.num <= T.first_num and score.num >= T.second_num;

c.union 合並查詢結果集

  • union 進行結果集合並要求結果集的列數相同,合並時列與列的數據類型也相同
  • 同時union合並時會自動去重,可以使用union all 進行保留
  • 減少匹配次數,實現數據集的拼接
  • union的效率要高一些(減少匹配次數),對於表連接而言,每連接一次新表,則匹配的次數滿足笛卡爾積
  • 實例:

​ 查詢工作崗位是manager 和salesman的員工

-- 第一種
select ename,job from emp where job='manager' or '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';

D、limit 分頁查詢

1.將數據集的一部分取出,通常使用在分頁查詢當中

  • 語法

    完整用法:limit  startindex,length 
    		startindex	 起始下標  length 長度
    		起始下標從0開始
    		
    缺省用法:limit num; 取前num個
    		limit 8  表示取前八個
    		
    
  • limit 與oder by的使用

    select ... from...
    order by  .. desc  limit 5
    

2.通用分頁

  • 每頁顯示3條記錄
    • 第1頁 : limit 0,3
    • 第2頁: limit 3,3
    • 第3頁: limit 6,3
    • 第4頁: limit 9,3
    • 第n頁: limit (num-1)*3,3


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM