1. 程式人生 > >mysql資料庫(3)--內,外連線查詢、子查詢、合併、分頁【入門】

mysql資料庫(3)--內,外連線查詢、子查詢、合併、分頁【入門】

可以參照前兩個帖子,按順序的,mysql資料庫(1)有完整的建表語句

mysql資料庫(1)---簡單查詢

mysql資料庫(2)---單行函式、多行函式、分組查詢

 

-- 簡單查詢語句的完整語法

/*完整語法

SELECT 查詢列表

FROM 表名

WHERE 查詢條件

CROUP BY 分組欄位

HAVING 查詢條件

ORDER BY 排序欄位

 

-- 以上語句的執行順序

-- 1,SELECT FROM 查詢出全部的資料

-- 2,使用WHERE對查詢結果進行過濾

-- 3,過濾後的資料使用GROUP BY進行分組

-- 4,分組後的資料使用HAVING再次過濾

-- 5,再次過濾後的資料用ORDER BY排序

 

-- 注意事項:

-- 1,以上語句的順序是固定的,不能改變

-- 2,對資料過濾得時候,優先使用WHERE進行過濾,這樣的效率比較高

*/

-- 把津貼為NULL的員工按照部門編號分組查詢平均工資,並且顯示平均工資大於XXX的資料,然後按照平均工資排序

SELECT dadtno,ROUND(AVG(sal)) "平均工資"

FROM emp

WHERE comm IS NOT NULL

GROUP BY dadtno

HAVING 平均工資>1000

ORDER BY 平均工資;

 

-- 【【1】】,連線查詢,也稱為多表查詢、跨表查詢;也就是從多個表中查詢相關的資料

-- 注意:多表查詢的時候,使用的表越多,查詢的速度越慢

-- 多表查詢的分類:

-- 1,按照連線的方式區分

-- (1)內連線:可以查詢滿足一一對應關係的資料;例如這個員工有所屬的部門,這個部門有所屬的員工,

-- 這樣的資料滿足一一對應的關係可以使用內連線查詢出來

-- (2)外連線:可以查詢不滿足一一對應關係的資料;例如這個員工沒有所屬的部門,這個部門沒有所屬的員工,

-- 這樣的資料不滿足一一對應的關係,使用內連線查詢出來是無法查詢的出來,但是可以使用外連線進行查詢

-- 2,按照語法的年代劃分

-- (1)SQL1992標準:FROM後面是多個表,多個表之間通過逗號分隔

-- (2)SQL1999標準:FROM後面是一個表,通過jOIN方式連線其他表

 

-- 【1.1】,內連線:可以查詢滿足一一對應關係的資料;例如這個員工有所屬的部門,這個部門有所屬的員工,

-- 這樣的資料滿足一一對應的關係可以使用內連線查詢出來

-- 內連線的分類:

-- (1)等值連線

-- (2)非等值連線

-- (3)自連線

-- 【1.1.1】,內連線之等值連線:建立在父子表關係上,用等號來連線兩個表

-- (1)sql1992語法

-- 1,查詢工資資訊及其部門資訊

SELECT e.ename,e.empNo,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e,dept d

WHERE e.dadtno = d.dadtno;

-- 2,在等值連線的基礎上,可以使用AND加入其他的查詢條件

SELECT e.ename,e.empNo,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e,dept d

WHERE (e.dadtno = d.dadtno) AND (d.dadtno=20);

-- 3,查詢工資在1600-3000之間的員工資訊及其部門資訊

-- 1,等值查詢 2,使用AND加入其他的查詢條件,過濾1660-3000的資料

SELECT e.ename,e.empNo,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e,dept d

WHERE (e.dadtno = d.dadtno) AND (e.sal BETWEEN 1600 AND 3000);

-- (2)sql1999語法

-- 使用內連線時,INNER可以忽略

SELECT e.ename,e.empNo,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

INNER JOIN dept d ON (e.dadtno = d.dadtno);

-- 2,在等值連線的基礎上,可以使用AND加入其他的查詢條件

SELECT e.ename,e.empNo,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

INNER JOIN dept d ON (e.dadtno = d.dadtno) AND (d.dadtno=20);

-- 3,查詢工資在1600-3000之間的員工資訊及其部門資訊

SELECT e.ename,e.empNo,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

INNER JOIN dept d ON (e.dadtno = d.dadtno)

WHERE (e.sal BETWEEN 1600 AND 3000);

-- 表salgrade

CREATE TABLE salgrade(

grade INT(10),

losal INT(10),

hisal INT(10)

)

 

-- 【1.1.2】,內連線之非等值連線,兩個表之間沒有父子關係,用非等號來連線

-- SQL1992語法

SELECT e.empNo,e.ename,e.sal,s.grade,s.losal,s.hisal

FROM emp e , salgrade s

WHERE (e.sal BETWEEN s.losal AND s.hisal);

-- 使用AND加入其他的查詢條件

SELECT e.empNo,e.ename,e.sal,s.grade,s.losal,s.hisal

FROM emp e , salgrade s

WHERE (e.sal BETWEEN s.losal AND s.hisal) AND (s.grade=1);

-- sql1999語法

SELECT e.empNo,e.ename,e.sal,s.grade,s.losal,s.hisal

FROM emp e

JOIN salgrade s ON (e.sal BETWEEN s.losal AND s.hisal);

-- 使用AND加入其他的查詢條件

SELECT e.empNo,e.ename,e.sal,s.grade,s.losal,s.hisal

FROM emp e

JOIN salgrade s ON (e.sal BETWEEN s.losal AND s.hisal) AND (s.grade=1);

-- 使用WHERE加入其他的查詢條件

SELECT e.empNo,e.ename,e.sal,s.grade,s.losal,s.hisal

FROM emp e

JOIN salgrade s ON (e.sal BETWEEN s.losal AND s.hisal) WHERE (s.grade=1);

 

-- 【1.1.3】,內連線之自連線:使用別名將一個表虛擬成為兩個表(父子表)然後在這兩個表上面做等值連線

-- 查詢員工的資訊及其直接領導的資訊

-- SQL1992語法

SELECT e.empNo "員工編號",e.ename "員工名字",m.empNo "經理編號",m.ename "經理名字"

FROM emp e,emp m

WHERE (e.mgr = m.empNo) AND (m.empNo=1239);

-- SQL1999語法

SELECT e.empNo "員工編號",e.ename "員工名字",m.empNo "經理編號",m.ename "經理名字"

FROM emp e

JOIN emp m ON (e.mgr = m.empNo) WHERE (m.empNo=1239);

 

 

-- 【1.2】,外連線:可以查詢不滿足一一對應關係的資料;例如這個員工沒有所屬的部門,這個部門沒有所屬的員工,

-- 這樣的資料不滿足一一對應的關係,使用內連線查詢出來是無法查詢的出來,但是可以使用外連線進行查詢

-- 使用外連線查詢資料的條數大於等於內連線查詢資料的條數

-- 資料庫把不匹配的資料設定為NULL;

-- 外連線的分類(可以把OUTER給忽略不寫)

-- (1)左外連線(LEFT OUTER JOIN)

-- (2)右外連線(RIGHT OUTER JOIN)

-- (3)全外連線(FULL OUTER JOIN)

 

-- 【1.2.1】,左外連線(LEFT OUTER JOIN):用LEFT OUTER JOIN作為分界線emp表就是左表,左外連線可以把左表中

-- 不滿足的對應關係的資料查詢出來;

-- 例如1243這個員工沒有對應的部門,可以查詢出來

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

LEFT JOIN dept d ON (e.dadtno = d.dadtno);

 

-- 【1.2.2】,右外連線(RIGHT OUTER JOIN)用RIGHT OUTER JOIN作為分界線,dept表示在右表;右連線可以把右表不滿足的資料查詢出來

-- 例如:40這個部門沒有對應的員工,可以被查出來

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

RIGHT JOIN dept d ON (e.dadtno = d.dadtno);

 

--【1.2 3】,左外連線的功能可以用右外連線的功能(左右表也可以互換)

-- 【1.2.4】,全外連線(FULL OUTER JOIN)用FULL OUTER JOIN作為分界線,把兩個表中不滿足對應關係的資料都查詢出來;

-- 在oracle支援;在mysql不支援,會報錯

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

FULL JOIN dept d ON (e.dadtno = d.dadtno);

-- 查詢員工及其領導的資訊;並顯示沒有領導的員工

SELECT e.empNo "員工編號",e.ename "員工姓名",m.empNo "經理編號",m.ename "經理名字"

FROM emp e

LEFT JOIN emp m ON (e.mgr = m.empNo);

 

-- 【【2】】,多表查詢

-- 從N個表中查詢相關的資料,需要N-1個INNER JOIN子句即可

-- 查詢員工資訊,部門資訊及其員工工資級別資訊,並是1000-3000的範圍

-- SQL1992語法

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc,s.grade,s.losal,s.hisal

FROM emp e,dept d,salgrade s

WHERE (e.dadtno = d.dadtno) AND (e.sal BETWEEN s.losal AND s.hisal) AND (e.sal BETWEEN 1000 AND 3000);

-- SQL1999語法

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc,s.grade,s.losal,s.hisal

FROM emp e

JOIN dept d ON (e.dadtno=d.dadtno)

JOIN salgrade s ON (e.sal BETWEEN s.losal AND s.hisal)

WHERE (e.sal BETWEEN 1000 AND 3000);

 

-- 【【3】】,子查詢:用來給主查詢提供查詢條件而首先執行的一個查詢;主查詢使用子查詢的結果;子查詢必須要放在()裡面

-- 子查詢的分類

-- 1,出現在WHERE中的子查詢;用來給查詢提供查詢條件的

-- 2,出現下在FROM後面的子查詢,用來給主查詢提供查詢資料的,也就是先執行子查詢,然後把子查詢的查詢結果當做一個虛表

-- 然後主查詢從這個虛表中查詢資料

-- 3,出現在查詢列表的子查詢,功能類似於連線效果,這種方式瞭解即可

-- 【3.1】,出現在WHERE中的子查詢;用來給查詢提供查詢條件的

-- 查詢工資比平均工資低的員工

SELECT *

FROM emp

WHERE sal < (SELECT AVG(sal) FROM emp);

 

--【3.2】,出現下在FROM後面的子查詢,用來給主查詢提供查詢資料的,也就是先執行子查詢,然後把子查詢的查詢結果當做一個虛表

-- 然後主查詢從這個虛表中查詢資料

SELECT T.*

FROM (SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc,s.grade,s.losal,s.hisal

FROM emp e

JOIN dept d ON (e.dadtno = d.dadtno)

JOIN salgrade s ON (e.sal BETWEEN s.losal AND s.hisal)) T

WHERE T.empNo = 1234;

 

-- 【3.3】,出現在查詢列表的子查詢,功能類似於連線效果,這種方式瞭解即可

SELECT e.*,(SELECT d.dname FROM dept d WHERE e.dadtno = d.dadtno) daname

FROM emp e;

 

-- 【【4】】,分組查詢,多表查詢,子查詢綜合應用

-- 1,取得每個部門最高薪水的員工名稱

-- 思路:按照部門編號分組查詢最高工資當做一個臨時表,和emp e表進行連線;連線條件(e.dadtno=T.dadtno AND e.sal = T.MAXsal)

SELECT T.dadtno,T.MAXsal,e.ename

FROM emp e

JOIN (

SELECT dadtno, MAX(sal) MAXsal

FROM emp

GROUP BY dadtno ) T ON (e.dadtno = T.dadtno AND e.sal = T.MAXsal)

ORDER BY T.dadtno;

 

-- 【【5】】,使用UNION把兩個表查詢結果合併成為一個查詢結果

-- 注意:合併兩個查詢結果的時候,要求兩個查詢結果必須一致(查詢欄位的型別、個數、順序必須一致)

-- UNION有兩種使用方式

-- 1,UNION:會合並相同的資料

-- 2,UNION ALL:不會合並相同的資料

-- 【5.1】,UNION:會合並相同的資料

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,e.dadtno

FROM emp e

WHERE e.sal>1000

UNION

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,e.dadtno

FROM emp e

WHERE e.sal>3000;

 

-- 【5.2】,UNION ALL:不會合並相同的資料

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,e.dadtno

FROM emp e

WHERE e.sal>1000

UNION ALL

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,e.dadtno

FROM emp e

WHERE e.sal>3000;

 

-- 【5.3】,使用UNION把一個左外連線的結果和右外連線的結果合併起來實現全外連線的效果

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

LEFT JOIN dept d ON (e.dadtno = d.dadtno)

UNION

SELECT e.empNo,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.dadtno,d.dname,d.loc

FROM emp e

RIGHT JOIN dept d ON (e.dadtno = d.dadtno);

 

-- 【【6】】,LIMIT的使用,可以查詢表中最高前面的幾條資料或中間某幾條資料

-- LIMIT的用法:LIMIN a,b;a是開始得索引(索引預設0開始);b是連線條數

-- 注意:LIMIT只能在mysql和SQLserver中有效

-- 使用LIMIN查詢最高工資前面4個一個資訊

SELECT *

FROM emp

GROUP BY sal DESC LIMIT 0,4;