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

MySQL 入門筆記:查詢進階(功能查詢、聯合查詢、交叉查詢、子查詢實戰)

     編輯:MySQL 綜合教學

超越基礎 CRUD,掌握功能查詢(DML 封裝)、聯合/交叉/子查詢,能解決 80% 的業務報表與數據處理需求。本文以實戰場景為導向,系統講解四大進階查詢類型。

功能查詢:DML 的集合化封裝

將 SELECT 篩選結果直接作為 UPDATE/DELETE/INSERT/CREATE TABLE 目標,實現批量操作。

類型語法模式場景
更新查詢UPDATE t SET col=expr WHERE condition;批量漲價、狀態流轉
刪除查詢DELETE FROM t WHERE condition;清理過期數據、軟刪除轉硬刪除
追加查詢INSERT INTO t(col1,col2) SELECT col1,col2 FROM src WHERE ...;數據歸檔、跨庫同步、報表落地
生成表查詢CREATE TABLE new_t AS SELECT ... FROM src ...;建立物化視圖、臨時分析表

實戰範例:將 2023 年已完成訂單歸檔至 orders_2023:


CREATE TABLE orders_2023 AS
SELECT * FROM orders
WHERE status=3 AND YEAR(created_at)=2023;

-- 驗證後再刪除主表數據
DELETE FROM orders WHERE status=3 AND YEAR(created_at)=2023;

聯合查詢:UNION / UNION ALL

  • UNION:合併結果集並 去重(排序+唯一),性能較差。
  • UNION ALL:直接合併,**不去重**,性能優,**生產首選**。

規則:各 SELECT 列數、列順序、類型兼容必須一致。


-- 統計所有渠道用戶註冊量(去重手機號)
SELECT mobile, 'channel_a' AS src FROM channel_a_users
UNION ALL
SELECT mobile, 'channel_b' FROM channel_b_users
UNION ALL
SELECT mobile, 'channel_c' FROM channel_c_users;

交叉查詢:樞紐分析 (Pivot)

MySQL 無原生 PIVOT,用 CASE WHEN + 聚合 模擬行轉列。


-- 統計各部門各季度銷售額
SELECT 
  dept_name,
  SUM(CASE WHEN QUARTER(sale_date)=1 THEN amount ELSE 0 END) AS Q1,
  SUM(CASE WHEN QUARTER(sale_date)=2 THEN amount ELSE 0 END) AS Q2,
  SUM(CASE WHEN QUARTER(sale_date)=3 THEN amount ELSE 0 END) AS Q3,
  SUM(CASE WHEN QUARTER(sale_date)=4 THEN amount ELSE 0 END) AS Q4,
  SUM(amount) AS total
FROM sales
JOIN depts ON sales.dept_id = depts.id
WHERE YEAR(sale_date)=2023
GROUP BY dept_name
ORDER BY total DESC;

大數據量交叉查詢建議預計算落地寬表或接入 ClickHouse/Doris。

子查詢:嵌套的邏輯復用

類型位置返回典型運算符
標量子查詢SELECT/WHERE/HAVING單值(1行1列)=, <>, >, <, >=, <=
列子查詢WHERE/HAVING單列多行IN, NOT IN, ANY, ALL
行子查詢WHERE單行多列=, <>, IN
表子查詢FROM/JOIN多行多列作為派生表
相關子查詢WHERE/SELECT引用外層列EXISTS, NOT EXISTS, IN

實戰範例:


-- 1. 標量:查詢最高薪資員工
SELECT * FROM employees WHERE salary = (SELECT MAX(salary) FROM employees);

-- 2. IN 列子查詢:有訂單的用戶
SELECT * FROM users WHERE id IN (SELECT DISTINCT user_id FROM orders);

-- 3. EXISTS 相關子查詢(通常比 IN 效率高,可用索引)
SELECT * FROM users u WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);

-- 4. 派生表:各用戶最新訂單
SELECT u.*, o.amount AS latest_amount
FROM users u
JOIN (
  SELECT user_id, amount, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) AS rn
  FROM orders
) o ON u.id = o.user_id AND o.rn = 1;

性能優化口訣

  • 能 JOIN 別子查詢:MySQL 5.6+ 對衍生表優化有限,JOIN 通常有更好執行計劃。
  • EXISTS 優於 IN:相關子查詢配合索引,可短路掃描。
  • 避免 SELECT 列表中放標量子查詢:每行執行一次,極慢,改用 JOIN 或應用層組裝。
  • 派生表物化:optimizer_switch='derived_merge=on' (默認) 可將衍生表合併到外層查詢,避免物化臨時表。

進階查詢的本質是「集合運算思維」:用 UNION 做加法、JOIN 做乘法、WHERE/HAVING 做過濾、GROUP BY 做聚合、子查詢 做邏輯封裝。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved