本日主題:更靈活的 WHERE 條件與排序、取前 N 名 預計時間:1.5 小時 對應主教材:第 6.1 節
一、今日學習目標
- [ ] 熟練各種 WHERE 條件運算子
- [ ] 會多欄位排序與取前 N 名
- [ ] 認識 CASE WHEN 條件表達式
二、教材內容
2.1 WHERE 常用運算子
WHERE salary > 50000 -- 大於
WHERE salary >= 50000 -- 大於等於
WHERE salary < 50000 -- 小於
WHERE salary <= 50000 -- 小於等於
WHERE department <> 'IT' -- 不等於(也可用 !=)
WHERE salary BETWEEN 45000 AND 55000 -- 介於(含兩端)
WHERE department IN ('IT','維修') -- 在清單內
WHERE name LIKE '王%' -- 開頭是「王」(% 是萬用字元)
WHERE name LIKE '%華' -- 結尾是「華」
WHERE hire_date IS NULL -- 是空值
WHERE hire_date IS NOT NULL -- 不是空值
2.2 多條件:AND / OR
-- AND:兩條件都要滿足
SELECT * FROM employees
WHERE department = 'IT' AND salary > 50000;
-- OR:任一條件滿足即可
SELECT * FROM employees
WHERE department = 'IT' OR department = '維修';
-- NOT:否定條件
SELECT * FROM employees
WHERE NOT department = 'IT';
混用 AND/OR 時用括號釐清優先順序:
WHERE (a OR b) AND c。
常見錯誤示範:
-- ❌ 錯誤:AND/OR 混用沒加括號,結果可能不如預期
SELECT * FROM employees
WHERE department = 'IT' OR department = '維修' AND salary > 50000;
-- 這等同於:WHERE department = 'IT' OR (department = '維修' AND salary > 50000)
-- 因為 AND 優先於 OR
-- ✓ 正確:加括號明確意圖
SELECT * FROM employees
WHERE (department = 'IT' OR department = '維修') AND salary > 50000;
2.3 排序與取前 N 名
-- 多欄位排序:先部門升冪,同部門再薪水降冪
SELECT * FROM employees
ORDER BY department ASC, salary DESC;
-- 取薪水前 3 名
SELECT name, salary FROM employees
ORDER BY salary DESC
LIMIT 3; -- MySQL/SQLite/PostgreSQL
-- SQL Server: SELECT TOP 3 name, salary FROM employees ORDER BY salary DESC
-- Oracle: SELECT name, salary FROM employees ORDER BY salary DESC FETCH FIRST 3 ROWS ONLY
2.4 LIKE 萬用字元
| 萬用字元 | 作用 | 範例 | 比對 |
|---|---|---|---|
% |
任意長度字元(含 0 個) | LIKE '王%' |
王、王小明、王大華 |
_ |
任意「單一」字元 | LIKE '王_明' |
王小明(中間剛好一個字) |
-- 姓名包含「華」
SELECT * FROM employees WHERE name LIKE '%華%';
-- 姓名第二個字是「大」
SELECT * FROM employees WHERE name LIKE '_大%';
2.5 CASE WHEN 條件表達式
CASE WHEN 像是 SQL 裡的 if-else,可以根據條件產生不同的值:
-- 基本語法
SELECT name, salary,
CASE
WHEN salary >= 55000 THEN '高薪'
WHEN salary >= 48000 THEN '中薪'
ELSE '一般'
END AS 薪資等級
FROM employees;
執行結果: | name | salary | 薪資等級 | |---|---|---| | 王小明 | 52000 | 中薪 | | 李大華 | 48000 | 中薪 | | 陳美麗 | 45000 | 一般 | | 林志強 | 60000 | 高薪 | | 張雅婷 | 55000 | 高薪 | | 黃建宏 | 47000 | 一般 |
-- 搭配 GROUP BY 使用:統計各薪資等級人數
SELECT
CASE
WHEN salary >= 55000 THEN '高薪'
WHEN salary >= 48000 THEN '中薪'
ELSE '一般'
END AS 薪資等級,
COUNT(*) AS 人數
FROM employees
GROUP BY
CASE
WHEN salary >= 55000 THEN '高薪'
WHEN salary >= 48000 THEN '中薪'
ELSE '一般'
END;
常見錯誤示範:
-- ❌ 錯誤:CASE WHEN 忘記 END
SELECT name,
CASE WHEN salary > 50000 THEN '高' ELSE '低'
FROM employees;
-- 正確:CASE ... END
-- ❌ 錯誤:WHEN 條件順序不對
SELECT name,
CASE
WHEN salary >= 48000 THEN '中薪' -- 這行先比對
WHEN salary >= 55000 THEN '高薪' -- 55000 也 >= 48000,永遠不會到這行
ELSE '一般'
END AS 等級
FROM employees;
-- 正確:從大到小排列 WHEN 條件
2.6 NULL 值的特殊處理
-- NULL 不能用 = 比較,要用 IS NULL / IS NOT NULL
-- ❌ 錯誤
SELECT * FROM employees WHERE hire_date = NULL;
-- ✓ 正確
SELECT * FROM employees WHERE hire_date IS NULL;
-- COALESCE:NULL 替換為預設值
SELECT name, COALESCE(department, '未指派') AS 部門
FROM employees;
三、常見誤解
| 誤解 | 正確觀念 |
|---|---|
| 「BETWEEN 不含邊界」 | BETWEEN 包含左右兩端(BETWEEN 45000 AND 55000 包含 45000 和 55000) |
| 「NULL = NULL 是 TRUE」 | NULL = NULL 結果是 NULL(未知),不是 TRUE。要用 IS NULL |
| 「LIKE '%' 效能跟 = 一樣」 | LIKE 開頭用 % 會導致全表掃描,無法使用索引,效能差 |
| 「LIMIT 在所有資料庫都能用」 | LIMIT 是 MySQL/SQLite/PostgreSQL 語法,SQL Server 用 TOP,Oracle 用 FETCH FIRST |
四、面試加分小知識
- Wildcard(萬用字元):
%和_的英文名稱。 - Short-circuit evaluation:SQL 的 AND/OR 可能有短路評估,AND 左邊為 FALSE 時不評估右邊。
- ILIKE:PostgreSQL 的大小寫不敏感 LIKE(MySQL 的 LIKE 預設就不分大小寫)。
- ESCAPE:當 LIKE 要搜尋含
%或_的實際字元時,用 ESCAPE 指定跳脫字元。
五、今日練習
Q1. 查薪水在 45000~55000 之間的員工。
Q2. 查 IT 或會計部門、且薪水大於 47000 的員工。
Q3. 查薪水最高的前 2 名(姓名、薪水)。
Q4. 用 CASE WHEN 將員工依薪水分為「高薪(>=55000)」「中薪(>=48000)」「一般」三級,顯示姓名與等級。
Q5. 查出所有姓「李」或姓「王」的員工。
參考解答
-- A1:薪水 45000~55000
SELECT * FROM employees WHERE salary BETWEEN 45000 AND 55000;
-- A2:(IT 或會計) 且薪水 > 47000
SELECT * FROM employees
WHERE department IN ('IT','會計') AND salary > 47000;
-- 或用括號明確表達:
-- WHERE (department = 'IT' OR department = '會計') AND salary > 47000;
-- A3:薪水前 2 名
SELECT name, salary FROM employees ORDER BY salary DESC LIMIT 2;
-- A4:CASE WHEN 薪資分級
SELECT name,
CASE
WHEN salary >= 55000 THEN '高薪'
WHEN salary >= 48000 THEN '中薪'
ELSE '一般'
END AS 薪資等級
FROM employees;
-- A5:姓李或姓王
SELECT * FROM employees
WHERE name LIKE '李%' OR name LIKE '王%';
六、延伸閱讀
- SQL CASE Expression (W3Schools) — CASE WHEN 詳細教學
- SQL NULL Values (W3Schools) — NULL 處理
七、今日檢核
- [ ] 我會用 BETWEEN/IN/LIKE 等運算子
- [ ] 我會用 AND/OR 組合條件(含括號)
- [ ] 我會多欄位排序與取前 N 名
- [ ] 我會用 CASE WHEN 做條件判斷
- [ ] 我知道 NULL 的特殊處理方式
⬅️ 上一天:Day 1 | 🏠 本週總覽 | ➡️ 下一天:Day 3 — 聚合與分組