MySQL資料庫-高階查詢
資料統計分析:
聚合函式:
聚合函式可以對資料求和,求最大值和最小值,求平均值等等。
1.AVG() 2.SUM()只能用於數字型別 3.MAX() 4.MIN() 5.AVG() 6.COUNT(*)用於獲得包含空值的記錄數
聚合函式不能出現在where語句裡面,原因很簡單,需要先執行where子句才能確定範圍,才能執行聚合函式,ON可以與WHERE替換。
分組查詢:
1.group by 子句(在where子句後面)
2.逐級分組:
SELECT deptno,job,COUNT(*),AVG(sal) FROM t_emp GROUPBY deptno,job ORDER BY deptno;(查詢每個部門裡每種職位的人員數量和平均底薪)
對select語句的要求:
查詢語句中如果含有group by子句,那麼select子句中的內容就必須要遵守規定:select子句中可以包括聚合函式,或者group by子句的分組列,其餘內容均不可以出現在select子句中。
3.對分組結構再次做彙總計算:
group by with rollup;
4.group_councat函式:
group_concat函式可以把分組查詢中的某個欄位拼接成一個字串。
SELECTdeptno,COUNT(*),GROUP_CONCAT(ename) FROM t_emp WHERE sal>=2000 GROUP BY deptno;
5.round函式——>將小數位四捨五入取整
各種子句的執行順序:from——>where——>group by——>select——>order by——>limit
HAVING 子句:(只能用在group by子句裡面,不能完全替代where子句)
解決在where語句內出現聚合函式的情況。(例如:查詢部門平均底薪超過2000元的部門編號)
SELECT deptno,ROUND(AVG(sal)) FROM t_emp GROUP BY deptno HAVING AVG(sal)>2000;
having子句裡面不能出現欄位(sal > avg(sal)),但可以出現具體數值(2000>avg(sal))必須要用表連線才行。
多表連線查詢:從多張表中提起資料,必須指定關聯條件,否則會產生笛卡爾積
內連線:
集中只保留符合連線條件的記錄。
內連線的多種語法形式:
1 SELECT ...... FROM 表1 JOIN 表2 ON 連線條件; 2 SELECT ...... FROM 表1 JOIN 表2 WHERE 連線條件; 3 SELECT ...... FROM 表1,表2 WHERE 連線條件;
查詢每個員工的工號,姓名,部門名稱,底薪,職位,工資等級: 1 SELECT e.deptno,e.ename,d.dname,e.sal,e.job,s.grade 2 FROM t_emp e JOIN t_dept d ON e.deptno = d.deptno 3 JOIN t_salgrade s ON e.sal BETWEEN s.losal AND s.hisal 4 ORDER BY s.grade;
內連線的資料表不一定必須有同名欄位,只要欄位之間符合邏輯關係就可以。
查詢與SCOTT相同部門的員工都有誰: SELECT ename FROM t_emp WHERE deptno = (SELECT deptno FROM t_emp WHERE ename = "SCOTT") AND ename != "SCOTT"; 這是子查詢的方法,但是子查詢會導致資料庫查詢效率降低
SELECT e1.ename FROM t_emp e1 JOIN t_emp e2 ON e1.deptno = e2.deptno WHERE e2.ename = "SCOTT" AND e1.ename != "SCOTT"; 使用內連線的方法,用相同表連線可以加快查詢效率
一些題目:
查詢底薪超過公司平均底薪的員工資訊(選擇查詢出來的表也可以進行表連線)
內查詢方法: SELECT ename FROM t_emp WHERE sal>(SELECT ROUND(AVG(sal)) from t_emp); 內連線方法: SELECT e.empno,e.ename,e.sal FROM t_emp e JOIN (SELECT ROUND(AVG(sal)) as avg FROM t_emp) t #新表格的連線 ON e.sal >= t.avg;
查詢research部門的人數,最高底薪,最低底薪,平均底薪,平均工齡:
SELECT COUNT(*),MAX(e.sal),MIN(e.sal),AVG(e.sal), FLOOR(AVG(DATEDIFF(now(),e.hiredate)/365)) FROM t_emp e JOIN t_dept d ON e.deptno = d.deptno WHERE d.dname="RESEARCH";
FLOOR函式(強制抹零)CEIL函式(強制進位)
查詢每個底薪超過部門平均底薪的員工資訊:
SELECT e.ename,e.deptno,e.sal,t.avg FROM t_emp e JOIN (SELECT deptno,AVG(sal) as avg FROM t_emp GROUP BY deptno) t ON e.deptno=t.deptno AND e.sal>t.avg;
外連線:
不管符不符合連線條件,記錄都要保留在結果中。比如有的臨時工沒有部門,但是這條資訊也要顯示出來。
left join:左連線(保留左邊的欄位右邊為null進行連線) right join:右連結(保留右邊的欄位左邊為null進行連線)
查詢每個部門的名詞和部門裡面的人數,如果沒有部門的員工,部門名稱用null代替:
使用union關鍵字將多個語句的查詢結果進行合併
(SELECT d.dname,COUNT(e.deptno) FROM t_dept d LEFT JOIN t_emp e ON d.deptno=e.deptno GROUP BY d.deptno ) UNION (SELECT d.dname,COUNT(*) FROM t_dept d RIGHT JOIN t_emp e ON d.deptno=e.deptno GROUP BY d.deptno);
※查詢每名員工的編號,姓名,部門,月薪,工資等級,工齡,上司編號,上司姓名,上司部門:
SELECT e.ename,e.empno,d.dname,e.sal+IFNULL(e.comm,0),s.grade, FLOOR(DATEDIFF(NOW(),hiredate)/365), t.dname AS mdname,t.empno AS mempno,t.ename AS mename FROM t_emp e LEFT JOIN t_dept d ON e.deptno = d.deptno LEFT JOIN t_salgrade s ON e.sal BETWEEN s.losal AND s.hisal LEFT JOIN ( SELECT e1.empno,e1.ename,d1.dname FROM t_emp e1 JOIN t_dept d1 ON e1.deptno = d1.deptno ) t ON e.mgr = t.empno
外連線注意事項:
內連線只保留符合條件的記錄,所以查詢條件寫在on子句和where子句中的效果是相同的。但是外連線裡,條件寫在where子句裡,不符合條件的記錄是會被過濾掉的,而不是保留下來。
子查詢:
單行子查詢:
多行子查詢:
查詢同事:
SELECT ename FROM t_emp WHERE deptno IN (SELECT deptno FROM t_emp WHERE ename IN("FORD","MARTIN")) AND ename NOT IN ("FORD","MARTIN");
where子句中的多行子查詢中,可以使用關鍵字IN,ALL,ANY,EXISTS(效率低)關鍵字來處理多行表示式結果集的條件判斷。
where子查詢:
執行效率最低,避免使用,換成表連線
from子查詢:
查詢效率最高
select子查詢:
查詢效率低下