查詢是 SQL 的核心。本文系統梳理 SELECT 全語法、單表過濾條件、LIMIT 分頁機制、聚合函數、UNION 合並、別名規範,並給出演練場景與避坑提示。
SELECT [DISTINCT] select_expr [, select_expr ...]
FROM table_references
[WHERE where_condition]
[GROUP BY {col_name | expr | position} [ASC|DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position} [ASC|DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
| 模式 | 語法 | 示例 | 說明 |
|---|---|---|---|
| 全列 | SELECT * FROM t | SELECT * FROM employee | 生產禁用,列變更導致應用報錯 |
| 指定列 | SELECT col1, col2 FROM t | SELECT id, name FROM product | 顯式列名,穩定契約 |
| 條件過濾 | WHERE expr | WHERE id = 1002 | 支持比較、范圍、集合、模糊、空值、復合 |
| 去重 | SELECT DISTINCT col | SELECT DISTINCT age FROM employee | 多列去重以元組整體比較 |
| 排序 | ORDER BY col [ASC|DESC] | ORDER BY id ASC, age DESC | NULL 排首 (ASC),多列按聲明順序排序 |
| 分頁 | LIMIT offset, count | LIMIT 0, 10 / LIMIT 10 OFFSET 0 | offset 從 0 起,超出不報錯返回空 |
-- 比較
= <> != < <= > >= !< !>
-- 范圍
BETWEEN 10 AND 20 -- 含邊界
NOT BETWEEN 10 AND 20
-- 集合
IN (1,2,3) / NOT IN (1,2,3)
-- 模糊
LIKE '北京%' -- % 任意長度(含0)
LIKE 'ar_c' -- _ 單字符
NOT LIKE '...'
-- 空值
IS NULL / IS NOT NULL
-- 復合
AND OR NOT
-- 優先級:NOT > AND > OR,建議用括號顯式分組
| 函數 | 用途 | 示例 | 注意 |
|---|---|---|---|
| COUNT(*) | 行數 | COUNT(*) FROM employee | 含 NULL 行 |
| COUNT(col) | 非空值數 | COUNT(dept_id) FROM employee | 忽略 NULL |
| SUM(col) | 求和 | SUM(score) FROM grade GROUP BY num | 僅數值類型 |
| AVG(col) | 平均值 | AVG(age) FROM employee | 忽略 NULL |
| MAX/MIN(col) | 極值 | MAX(score) FROM grade GROUP BY course | 字符按 ASCII 比較 |
-- 分組查詢
SELECT dept_id, COUNT(*) AS cnt FROM employee GROUP BY dept_id;
-- 分組過濾
SELECT dept_id, COUNT(*) FROM employee GROUP BY dept_id HAVING COUNT(*) >= 5;
-- 帶 ROLLUP 超級聚合
SELECT dept_id, COUNT(*) FROM employee GROUP BY dept_id WITH ROLLUP;
-- 最後一行 dept_id=NULL 為總計
-- 去重合並(預設)
SELECT id, name FROM t1 WHERE id < 10
UNION
SELECT id, name FROM t2 WHERE id > 100;
-- 全量合並(保留重複,性能更好)
SELECT id, name FROM t1
UNION ALL
SELECT id, name FROM t2;
規則: 兩側列數、類型、順序必須一致;ORDER BY、LIMIT 僅能加在最後,需用括號包裹子查詢。
-- 表別名(簡化多表查詢)
SELECT e.id, e.name, d.name AS dept_name
FROM employee e
JOIN department d ON e.dept_id = d.id;
-- 列別名(AS 可省略,建議保留)
SELECT id AS user_id, name AS user_name FROM employee;
SELECT id user_id, name user_name FROM employee; -- 合法但可讀性差
SELECT * 禁止在生產代碼出現WHERE col = NULL 永遠為 FALSE,必須用 IS NULLNOT IN (subquery) 子查詢返回含 NULL 導致全表掃描,改用 NOT EXISTSLIMIT 無 ORDER BY 結果不確定,分頁必須帶確定性排序WHERE,需 HAVING 或子查詢WHERE phone = 13800000000 應加引號ROW_NUMBER() 8.0+)LEFT JOIN ... WHERE o.id IS NULL 或 NOT EXISTS)熟練掌握基礎查詢語法,是寫出高性能、可維護 SQL 的前提。建議在測試庫建立標準練習數據集,每周完成一道「SQL 進階題」,養成肌肉記憶。