mysql 資料庫快速入門 多表查詢
目錄
多表查詢
多表查詢有如下幾種:
-
合併結果集
-
連線查詢
- 內連線 [INNER] JOIN ON
- 外連線 OUTER JOIN ON
- 左外連線 LEFT [OUTER] JOIN
- 右外連線 RIGHT [OUTER] JOIN
- 全外連線(MySQL不支援)FULL JOIN
- 自然連線 NATURAL JOIN
-
巢狀查詢
合併結果集
作用:合併結果集就是把兩個select語句的查詢結果合併到一起
要求:被合併的兩個結果:列數、列型別必須相同。
UNION :去除重複記錄
SELECT * FROM t1 UNION SELECT * FROM t2;
UNION ALL :不去除重複記錄
SELECT * FROM t1 UNION ALL SELECT * FROM t2;
連線查詢(非常重要)
連線查詢就是求出多個表的乘積,例如t1連線t2,那麼查詢出的結果就是t1*t2。
連線查詢會產生笛卡爾積,假設集合A={a,b},集合B={0,1,2},則兩個集合的笛卡爾積為{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。
多表查詢產生這樣的結果並不是我們想要的,那麼怎麼去除重複的,不想要的記錄呢,當然是通過條件過濾。通常要查詢的多個表之間都存在關聯關係,那麼就通過關聯關係去除笛卡爾積。
// 使用主外來鍵關係做為條件來去除無用資訊 SELECT * FROM emp,dept WHERE emp.deptno=dept.deptno[在多表查詢中,在使用列時必須指定列所從屬的表,例如emp.deptno表示emp表的deptno列。]; // 還可以為表指定別名,然後在引用列時使用別名即可。 SELECT e.ename,e.sal,e.comm,d.dname FROM emp AS e,dept AS d WHERE e.deptno=d.deptno;[其中AS是可以省略的]
內連線
上面的連線語句就是內連線,但它不是SQL標準中的查詢方式,可以理解為方言!SQL標準的內連線為。
內連線的特點:查詢結果必須滿足條件。例如我們向emp表中插入一條記錄。
SELECT *
FROM emp e
INNER[INNER可以省略,MySQL預設的連線方式就是內連線] JOIN dept d
ON[不使用WHERE,而是使用ON] e.deptno=d.deptno;
外連線(左連線、右連線)
- 外連線的特點:查詢出的結果存在不滿足條件的可能。
左連線:左連線是先查詢出左表(即以左表為主),然後查詢右表,右表中滿足條件的顯示出來,不滿足條件的顯示NULL
SELECT * FROM emp e
LEFT OUTER[OUTER可以省略] JOIN dept d
ON e.deptno=d.deptno;
右連線:右連線就是先把右表中所有記錄都查詢出來,然後左表滿足條件的顯示,不滿足顯示NULL
SELECT * FROM emp e
RIGHT OUTER JOIN dept d
ON e.deptno=d.deptno;
連線查詢心得:
連線不限與兩張表,連線查詢也可以是三張、四張,甚至N張表的連線查詢。通常連線查詢不可能需要整個笛卡爾積,而只是需要其中一部分,那麼這時就需要使用條件來去除不需要的記錄。這個條件大多數情況下都是使用主外來鍵關係去除。
自然連線
大家也都知道,連線查詢會產生無用笛卡爾積,我們通常使用主外來鍵關係等式來去除它。而自然連線無需你去給出主外來鍵等式,它會自動找到這一等式。
兩張連線的表中名稱和型別完全一致的列作為條件,例如emp和dept表都存在deptno列,並且型別一致,所以會被自然連線找到!
當然自然連線還有其他的查詢條件的方式,但其他方式都可能存在問題!
SELECT * FROM emp NATURAL JOIN dept;[內連線]
SELECT * FROM emp NATURAL LEFT JOIN dept;[左連線]
SELECT * FROM emp NATURAL RIGHT JOIN dept;[右連線]
巢狀(子)查詢(非常重要)
一個select語句中包含另一個完整的select語句。子查詢就是巢狀查詢,即SELECT中包含SELECT,如果一條語句中存在兩個,或兩個以上SELECT,那麼就是子查詢語句了。
子查詢出現的位置
- where後,作為條為被查詢的一條件的一部分;
- from後,作表;
當子查詢出現在where後作為條件時,還可以使用如下關鍵字
- any
- all
子查詢結果集的形式
- 單行單列(用於條件)
- 單行多列(用於條件)
- 多行單列(用於條件)
- 多行多列(用於表)
// 子查詢作為條件 子查詢形式為單行單列
// 工資高於JONES的員工
SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE ename='JONES')
// 子查詢作為條件 子查詢形式為多行單列(當子查詢結果集形式為多行單列時可以使用ALL或ANY關鍵字)
// 工資高於30號部門所有人的員工資訊
SELECT * FROM emp WHERE sal > ALL [大於所有](SELECT sal FROM emp WHERE deptno=30)
// 子查詢作為條件 子查詢形式為單行多列
// 查詢工作和工資與MARTIN(馬丁)完全相同的員工資訊
SELECT * FROM emp WHERE (job,sal) IN (SELECT job,sal FROM emp WHERE ename='MARTIN')
// 子查詢作為表 子查詢形式為多行多列
// 查詢員工編號為7788的員工名稱、員工工資、部門名稱、部門地址
SELECT e.ename, e.sal, d.dname, d.loc
FROM emp e, (SELECT dname,loc,deptno FROM dept) d
WHERE e.deptno=d.deptno AND e.empno=7788
自連線:自己連線自己,起別名
// 求7369員工編號、姓名、經理編號和經理姓名
SELECT e1.empno , e1.ename,e2.mgr,e2.ename
FROM emp e1, emp e2
WHERE e1.mgr = e2.empno AND e1.empno = 7369;