1. 程式人生 > 實用技巧 >MySQL資料庫-高階查詢

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 GROUP
BY deptno,job  ORDER BY deptno;(查詢每個部門裡每種職位的人員數量和平均底薪) 

    對select語句的要求:

       查詢語句中如果含有group by子句,那麼select子句中的內容就必須要遵守規定:select子句中可以包括聚合函式,或者group by子句的分組列,其餘內容均不可以出現在select子句中。

    3.對分組結構再次做彙總計算:

  group by with rollup;

    4.group_councat函式:

       group_concat函式可以把分組查詢中的某個欄位拼接成一個字串。  

 SELECT
deptno,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
) UNIONSELECT 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子查詢:

    查詢效率低下