首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL SELECT 進階技巧筆記:分頁、群組、模糊查詢與多表連接實戰

     編輯:MySQL 資料庫相關知識

SQL 查詢是後端開發的核心技能。本文整理 SELECT 實用技巧:語句格式、批次查詢、字串連接、定位搜尋、群組聚合、條件篩選、去重、分頁、多表連接,附帶常見陷阱與優化提示。

1. SQL 語句換行與可讀性

MySQL 允許 SQL 字串跨行,建議長查詢採用多行縮排:

$sql = "SELECT *
        FROM article
        WHERE id = 1";

便於維護與除錯,特別是動態組裝 SQL 時。

2. 批次查詢:IN 條件

SELECT * FROM article WHERE id IN (1,3,5);
  • 適用於已知 ID 列表的批次抓取,避免多次往返資料庫。
  • 列表過長(>1000)建議改用臨時表或 JOIN 衍生表。

3. 結果欄位字串連接:CONCAT

SELECT CONCAT(id, '-', content) AS res FROM article WHERE id = 1;
-- 輸出: 1-article content

常用於前端直接顯示的組合欄位(如「姓名-工號」)。

4. 字串定位:LOCATE / POSITION / INSTR

SELECT LOCATE('hello', 'hello baby'); -- 返回 1(找到位置)
SELECT LOCATE('xyz', 'hello baby');   -- 返回 0(不存在)
  • LOCATE(substr, str[, pos]) 可指定起始搜尋位置。
  • 搭配 WHERE LOCATE(keyword, column) > 0 實現簡易全文搜尋(小資料量)。

5. 群組聚合:GROUP BY

-- 列出每個城市的客戶數
SELECT city, COUNT(*) AS cnt FROM customer GROUP BY city;
  • GROUP BY 將相同值的列分為一組,配合聚合函數(COUNT, SUM, AVG, MAX, MIN)產出統計。
  • 注意: MySQL 5.7+ ONLY_FULL_GROUP_BY 模式下,SELECT 清單中的非聚合欄位必須出現在 GROUP BY 中。

6. 群組條件篩選:HAVING

SELECT city, COUNT(*) AS cnt, MIN(birth_day) AS earliest
FROM customer
GROUP BY city
HAVING COUNT(*) > 10;
  • HAVING 在分組後篩選,可使用聚合函數;WHERE 在分組前篩選,不可用聚合函數。
  • HAVING 中的運算式必須在 SELECT 或 GROUP BY 中出現過(或為聚合函數)。
  • 效能提示:GROUP BY + HAVING 較慢,能用 WHERE 先過濾盡量用 WHERE。

7. 子句執行順序

邏輯執行順序(非語法順序):

FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT

撰寫 SQL 時按語法順序:SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... LIMIT。

8. 去重:DISTINCT

SELECT DISTINCT city FROM customer ORDER BY id DESC;
  • 針對 SELECT 清單所有欄位組合去重。
  • 若需單欄去重但保留其他欄位,改用 GROUP BY 或視窗函數(MySQL 8.0+ ROW_NUMBER())。

9. 分頁:LIMIT

-- 跳過前 100 筆,取後續所有(-1 表示無上限)
SELECT * FROM article LIMIT 100, -1;

-- 標準分頁:第 3 頁,每頁 20 筆
SELECT * FROM article LIMIT 40, 20;  -- OFFSET 40 ROWS FETCH NEXT 20 ROWS ONLY (MySQL 8.0)
  • LIMIT offset, count 或 LIMIT count OFFSET offset。
  • 大偏移量(如 LIMIT 1000000, 20)效能差,建議改用游標分頁(WHERE id > last_id LIMIT 20)。

10. 多表連接查詢

SELECT u.user_name
FROM user u
JOIN member m ON u.id = m.id
WHERE m.reg_date >= '2006-12-28'
ORDER BY u.id DESC;
  • 使用表別名(u, m)簡化欄位引用。
  • 關鍵: 同名欄位必須加前綴(u.user_name),否則報錯 Column 'user_name' in field list is ambiguous。
  • 優先使用明確 JOIN ... ON 語法,避免舊式逗號連接產生笛卡兒積。
  • 驅動表(小結果集)放前面,配合索引加速。

常見陷阱速查

情境錯誤做法正確做法
GROUP BY 非聚合欄位SELECT id, city, COUNT(*) FROM t GROUP BY city加入 id 到 GROUP BY 或用聚合函數 MAX(id)
WHERE 用聚合函數SELECT city FROM t WHERE COUNT(*) > 10改用 HAVING COUNT(*) > 10
分頁大偏移LIMIT 1000000, 20游標分頁 WHERE id > 1000000 LIMIT 20
多表同名欄位SELECT user_name FROM u, m WHERE u.id=m.id加別名 SELECT u.user_name ...

熟練這些技巧,能寫出更精準、高效、可維護的 SQL 查詢。

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