首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 查詢語句完全指南:GROUP BY、UNION、子查詢、JOIN 類型與優化技巧

     編輯:MySQL 綜合教學

MySQL 查詢語句完全指南:GROUP BY、UNION、子查詢、JOIN 類型與優化技巧

系統梳理 MySQL 查詢核心語法:分組排序、UNION 合並、子查詢分類與用法、各類 JOIN 含義與陷阱、自然連接、外連接細節,附實測圖示與優化清單。

一、基礎查詢子句順序 (GHOL)

SELECT [DISTINCT] col_list
FROM tbl
[WHERE cond]
[GROUP BY col_list [WITH ROLLUP]]
[HAVING group_cond]
[ORDER BY col_list [ASC|DESC]]
[LIMIT offset, row_count]
  • DISTINCT:全行去重,SELECT DISTINCT * 幾乎無意義(全列相同才算重複)。
  • GROUP BY:非聚合列必須出現在 GROUP BY 中 (ONLY_FULL_GROUP_BY 模式),否則結果不確定。
  • HAVING:針對分組結果過濾,可用聚合函數;WHERE 不能用聚合函數。

二、UNION 合並結果集

(SELECT id, name, english FROM student ORDER BY english DESC LIMIT 1)
UNION
(SELECT id, name, math FROM student ORDER BY math DESC LIMIT 1);
  • 預設 UNION = UNION DISTINCT,去重;UNION ALL 保留重複,效能更高。
  • 子查詢 ORDER BY 需配合 LIMIT 才生效,否則被優化器忽略。
  • 全局排序只需在最後一個 SELECT 後加 ORDER BY。
  • 列數、類型、順序必須一致;結果列名以第一個 SELECT 為準。

三、子查詢分類與用法

分類返回位置典型運算符示例
標量單值WHERE/SELECT=, >, <, <=, >=, !=WHERE english = (SELECT MAX(english) FROM student)
列子查詢單列多行WHEREIN, NOT IN, ANY, ALL, SOMEWHERE class IN (SELECT class FROM student WHERE english > 90)
行子查詢單行多列WHERE=, !=, IN (需加括號)WHERE (class, math) = (SELECT class, math FROM student WHERE id=8)
表子查詢多行多列FROM衍生表 (必須別名)SELECT * FROM (SELECT * FROM student WHERE class='php103') t WHERE english < 60
EXISTSBOOLWHEREEXISTS / NOT EXISTSSELECT * FROM a WHERE EXISTS (SELECT 1 FROM b WHERE b.id = a.id)

ANY/ALL/SOME 進階

  • = ANY ≡ IN;!= ALL ≡ NOT IN。
  • > ALL (sub):大於子查詢最大值;> ANY (sub):大於子查詢最小值。
  • 含 NULL 時三值邏輯需謹慎,生產建議改寫為 IN/EXISTS。

四、JOIN 連接查詢詳解

1. 內連接 (INNER JOIN)

  • 預設 JOIN = INNER JOIN。
  • ON 放連接條件,WHERE 放過濾條件;內連接兩者等價,但語義不同。
  • USING(col):要求雙表同名列,結果自動去重該列並置首。

2. 外連接

類型保留邊語法關鍵限制
左外連接左表LEFT [OUTER] JOINON 必須寫連接條件,不可用 WHERE 連接
右外連接右表RIGHT [OUTER] JOIN同左
全外連接雙邊不支援LEFT JOIN UNION RIGHT JOIN 模擬
-- 左連接:教師表保留所有,無排課記錄也顯示
SELECT t.name, tc.class_id
FROM teacher t
LEFT JOIN teacher_class tc ON t.id = tc.teacher_id;

3. 自然連接

  • NATURAL JOIN:自動匹配所有同名列,不可控,易因新增同名列導致語義變更,生產嚴禁。
  • 同樣有 NATURAL LEFT/RIGHT JOIN。

4. 交叉連接 (CROSS JOIN)

  • 笛卡爾積,m × n 行,極度危險,僅用於測試生成組合數據。
  • MySQL 中 CROSS JOIN ≡ INNER JOIN (無 ON 時)。

五、別名與列名最佳實踐

  • 表別名:t, u, p 短小清晰,有別名後全程必須用別名,原表名失效。
  • 列別名:col AS alias 或 col alias,ORDER BY/GROUP BY/HAVING 可直接用別名。
  • 連接條件列名 建議加表前綴 (t.id = u.t_id),避免歧義。

六、優化清單

  1. EXPLAIN 看 type (目標 ref/eq_ref)、rows、Extra (避免 Using temporary; Using filesort)。
  2. 被驅動表連接列 必須有索引。
  3. 小表驅動大表:SELECT ... FROM small JOIN big ON ...。
  4. 只查需要的列,禁用 SELECT *。
  5. 外連接必要時改寫為 NOT EXISTS 或 LEFT JOIN ... WHERE right.pk IS NULL (反模式查詢)。
  6. 衍生表 (FROM 子查詢) MySQL 5.7+ 支援 derived_merge 優化,8.0 更強;舊版本考慮物化臨時表。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved