1. 程式人生 > >MySQL學習(三、分組查詢和多表查詢)

MySQL學習(三、分組查詢和多表查詢)

一、分組查詢

1.MySQL查詢函式

    函式的分類:
    1,單行函式:將每條資料進行獨立的計算,然後每條資料得到一條結果。
    2,多行函式:多條資料同時計算,最終得到一條結果資料。也成為聚集函式、分組函式, 主要用於完成一些統計功能。


2.什麼是分組?

    針對於班上所有的同學:
    分組情況1-按照性別分組:男生一組,女生一組,之後可以統計男生和女生的數量;
    分組情況2-按照年齡段分組:80後一組,90後一組;
    分組情況3-按照籍貫分組:廣東一組,湖南一組,江西一組;

3.分組查詢語法

語法:
SELECT  *|colName1,colName2,..|統計函式
FROM tName
[WHERE 條件]
GROUP BY colName1,[colName2],[...]
[ORDER BY colName1,colName2];
------------------------------------------------------
使用GROUP BY子句將表分成小組組函式忽略空值,可以使用ifnull
結果集隱式按升序排列,如果需要改變排序方式可以使用order by 子句

.使用GROUP BY

1,出現在SELECT列表中的欄位,如果出現的位置不是在組函式中,那麼必須出現在GROUP BY子句中。
2,在GROUP BY 子句中出現的欄位,可以不出現在SELECT列表中
3,如果沒有GROUP BY子句SELECT列表中的任何列或表示式不能使用統計函式。(不合理操作,Oracle會直接報錯)(沒有分組GROUP BY,查詢沒有意義)
-----------------------------------------------------------------------------
分組函式單獨使用:
SELECT COUNT(empno) FROM emp;
錯誤的使用,出現了其他欄位:
SELECT empno,COUNT(empno) FROM emp;     //FALSE


----------------------------------------------------------------------------
如果現在要進行分組的話,則SELECT子句之後,只能出現分組的欄位和統計函式,其他的欄位不能出現:
正確做法:
SELECT job,COUNT(empno),AVG(sal)
FROM emp
GROUP BY job;
錯誤的做法:
SELECT deptno,job,COUNT(empno),AVG(sal)
FROM emp
GROUP BY job;
-----------------------------------------------------------------------------
組函式的錯誤用法:
1,不能在 WHERE 子句中限制組。
2,限制組必須使用 HAVING 子句。
3,不能在 WHERE 子句中使用組函式。


需求:按照職位分組,求出每個職位的最高和最低工資




6.使用HAVING子句對分組的結果進行限制

SELECT *|colName1,colName2,... | 統計函式
FROM tName
WHERE 條件1
GROUP BY colName1,colName2,..
[HAVING 分組後的過濾條件(可以使用統計函式)]
[ORDER BY 排序欄位 ASC | DESC [,排序欄位 ASC | DESC]];


*注意點:WHERE和HAVING的區別
WHERE:是在執行GROUP BY操作之前進行的過濾,表示從全部資料之中篩選出部分的資料,在WHERE之中不能使用統計函式;
HAVING:是在GROUP BY分組之後的再次過濾,可以在HAVING子句中使用統計函式;


二、多表查詢

        單表查詢:從一張表中查詢資料
            SELECT col1,col2,col3
            FROM tName
    
        多表查詢:從多張表中聯合查詢出資料
            SELECT <selectlist> From tName1,tName2

1.笛卡爾積
     沒有連線條件的表關係返回的結果,多表查詢會產生笛卡爾積
     假設集合A={a,b},集合B={0,1,2},則兩個集合的笛卡爾積為{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}
     實際執行環境下,應避免使用全笛卡爾積
     解決辦法:在where子句中加入有效的連線條件---->等值連線(連線n張表,至少需要n-1個連線條件)
    
主鍵約束(PRIMARY KEY)
    約束在當前表中,指定列的值非空且唯一
外來鍵約束(FORGEIGN KEY
     主表的外來鍵列必須要引用於(參照)從表的主鍵列(避免無資料值)
     為了保證資料的合理性,我們需要建立外來鍵約束關係,
     規定:

        外來鍵值應該來源於從表的主鍵值

     一般我們定義外來鍵的時候,習慣命名:引用表名_引用列名
    在開發中,我們有時候為了提高效能,會故意刪除外來鍵約束,此時我們可以通過java程式碼來控制資料的合理性

    
    注意:在MYSQL中,innoDB支援事務和外來鍵。修改表的儲存引擎為innoDB
          ALTER TABLE tName ENGINE='InnoDB'(InnoDB儲存引擎,支援外來鍵又支援事務)
  


    
2.內連線
    內連線:相對於外連線的查詢
    內連線分為:隱式內連線、顯示內連線,查詢效果相同

    隱式內連線(常用):
    SELECT <selectlist> FROM A,B WHERE A.col=B.col
    顯示內連線(推薦):
    SELECT <selectlist> FROM A [INNER] JOIN B ON A.col=B.col

隱式內連線連線(看不到JOIN):

SELECT [DISTINCT] * | 欄位 [別名] [,欄位 [別名] ,…]
FROM 表名稱 [別名], [表名稱 [別名] ,…]
[WHERE 條件(S)]
[ORDER BY 排序欄位 [ASC|DESC] [,排序欄位 [ASC|DESC] ,…]];
-------------------------------------------------------------------------
使用表連線從多個表中查詢資料
SELECT    table1.column, table2.column
FROM        table1, table2
WHERE    table1.column1 = table2.column2;

在 WHERE 子句中寫入連線條件當多個表中有重名列時,必須在列的名字前加上表名作為字首/或使用表的別名

等值連線是連線操作中最常見的一種,通常是在存在主外來鍵約束條件的多表上建立的,連線條件中的兩個欄位通過等號建立等值關係。

使用表的別名簡化了查詢提高了查詢的效能
SELECT e.empno,e.ename,d.deptno,d.dname FROM emp e,dept d WHERE e.deptno = d.deptno;

顯示內連線查詢(查詢效果和隱式內連線相同):
SELECT    table1.column, table2.column
FROM    table1 INNER JOIN table2  ON(table1.column_name = table2.column_name)

自然連線的條件是基於表中所有同名列的等值連線為了設定任意的連線條件或者指定連線的列,需要使用ON子句連線條件與其它的查詢條件分開書寫使用ON 子句使查詢語句更容易理解

練習,使用顯式內連線查詢:
需求:查詢員工編號,員工名稱,員工所屬部門名稱.
SELECT e.empno,e.ename,d.dname  FROM emp e JOIN dept d ON  e.deptno = d.deptno
SELECT e.empno,e.ename,d.dname  FROM emp e JOIN dept d  USING(deptno)


3.外連線
外連線查詢(左外,右外,全外): 根據表在JOIN左邊還是右邊來區分.
      左外連線:查詢出JOIN左邊表的全部資料查詢出來,JOIN右邊的表不匹配的資料使用NULL來填充資料.
      右外連線:查詢出JOIN右邊表的全部資料查詢出來,JOIN左邊的表不匹配的資料使用NULL來填充資料.
      MYSQL中暫時不支援全連線
      可以通過union +左右連線來完成;
------------------------------------------------
在查詢語句中,一張表可以重複使用多次,完成多次連線的需要;
需求:查詢員工名稱和其對應經理的名稱.
SELECT e.empno,e.ename,m.ename FROM emp e LEFT JOIN emp m ON e.mgr = m.empno;
   
    *表別名:直接在表名後面空格,加上表別名(縮寫)
    *自連線查詢: 把一張表看成兩張表來查詢