對應教材:第 6.1 節 本週目標:把 SQL 練到能當場手寫查詢,這是 MIS 職位的關鍵技能 每日投入:1.5 ~ 2 小時 本週產出:在 SQLite / MySQL 練完 30 題查詢


本週學習目標

  • [ ] 熟練 SELECT / WHERE / ORDER BY
  • [ ] 熟練 GROUP BY / 聚合函數 / HAVING
  • [ ] 會 JOIN 多表查詢(INNER / LEFT / RIGHT)
  • [ ] 會 INSERT / UPDATE / DELETE(且知道 WHERE 的重要)
  • [ ] 理解 SQL 執行順序
  • [ ] 會用子查詢(Subquery)
  • [ ] 理解 NULL 的特殊行為
  • [ ] 能不看資料手寫面試常考的 SQL 題

每日進度

Day 1:環境準備 + 基本查詢

  • 安裝 SQLite(最輕量)或用線上 SQL 練習平台(如 SQLiteOnline、DB Fiddle)
  • 建立 employeesdepartments 兩張表並塞測試資料
-- 建表
CREATE TABLE departments (
    id INTEGER PRIMARY KEY,
    dept_name TEXT NOT NULL
);

CREATE TABLE employees (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    department TEXT,
    dept_id INTEGER,
    salary INTEGER,
    hire_date DATE,
    FOREIGN KEY (dept_id) REFERENCES departments(id)
);

-- 塞測試資料
INSERT INTO departments VALUES (1, '資訊部'), (2, '業務部'), (3, '產線部'), (4, '管理部');

INSERT INTO employees VALUES
(1, '王小明', 'IT', 1, 55000, '2023-03-15'),
(2, '李小華', 'IT', 1, 48000, '2024-01-10'),
(3, '張大偉', 'Sales', 2, 42000, '2022-06-01'),
(4, '陳美麗', 'IT', 1, 62000, '2021-08-20'),
(5, '林志強', 'Production', 3, 38000, '2024-05-12'),
(6, '黃小芳', 'Sales', 2, 45000, '2023-11-03'),
(7, '吳建宏', 'Production', 3, 40000, '2022-09-18'),
(8, '趙雅琪', 'Admin', 4, 50000, '2021-03-01'),
(9, '周大鵬', 'IT', 1, 58000, '2023-07-22'),
(10, '鄭小蓮', 'Production', 3, 36000, '2024-08-01');
  • 基本查詢練習:
-- 查所有欄位
SELECT * FROM employees;

-- 查特定欄位
SELECT name, salary FROM employees;

-- 篩選 + 排序
SELECT name, salary FROM employees
WHERE department = 'IT'
ORDER BY salary DESC;

-- 限制筆數
SELECT name, salary FROM employees
ORDER BY salary DESC
LIMIT 5;

Day 2:篩選與排序進階

  • WHERE 條件運算子
運算子 用途 範例
= 等於 WHERE dept = 'IT'
<> 或 != 不等於 WHERE dept <> 'IT'
> < >= <= 比較 WHERE salary > 50000
BETWEEN 範圍(含頭尾) WHERE salary BETWEEN 40000 AND 50000
IN 多值比對 WHERE dept IN ('IT', 'Sales')
LIKE 模糊比對 WHERE name LIKE '王%'
IS NULL 判斷空值 WHERE dept_id IS NULL
IS NOT NULL 判斷非空 WHERE dept_id IS NOT NULL
AND / OR 組合條件 WHERE dept = 'IT' AND salary > 50000
NOT 否定 WHERE NOT department = 'IT'
  • LIKE 萬用字元:% = 任意多字元、_ = 恰好一個字元
  • ORDER BY 多欄位排序:ORDER BY department ASC, salary DESC
  • LIMIT(MySQL/SQLite)、TOP(SQL Server)、FETCH FIRST N ROWS ONLY(Oracle/標準SQL)
  • NULL 的特殊行為
  • NULL 不等於任何值,包括自己(NULL = NULL 是 FALSE)
  • 必須用 IS NULL / IS NOT NULL 判斷
  • 聚合函數會忽略 NULL(除了 COUNT(*))

Day 3:聚合與分組

-- 基本聚合函數
SELECT
    COUNT(*) AS 總人數,
    AVG(salary) AS 平均薪資,
    MAX(salary) AS 最高薪,
    MIN(salary) AS 最低薪,
    SUM(salary) AS 薪資總額
FROM employees;

-- 分組統計
SELECT department,
       COUNT(*) AS 人數,
       AVG(salary) AS 平均薪資,
       MAX(salary) AS 最高薪
FROM employees
GROUP BY department;

-- HAVING 篩選分組結果
SELECT department, COUNT(*) AS 人數, AVG(salary) AS 平均薪資
FROM employees
GROUP BY department
HAVING COUNT(*) > 2;
  • 釐清 WHERE(分組前篩列)vs HAVING(分組後篩組)
  • WHERE:先篩選哪些「列」要進來
  • GROUP BY:把篩選後的列做分組
  • HAVING:對分組結果做篩選
  • 範例:「各部門人數超過 2 人且排除薪水低於 35000 的員工」 sql SELECT department, COUNT(*) AS 人數 FROM employees WHERE salary >= 35000 -- 先篩掉薪水太低的(列層級) GROUP BY department HAVING COUNT(*) > 2; -- 再篩人數超過 2 的部門(組層級)

  • 常用聚合函數:

函數 功能 注意
COUNT(*) 計算列數(含 NULL)
COUNT(欄位) 計算非 NULL 的列數
SUM(欄位) 加總 忽略 NULL
AVG(欄位) 平均 忽略 NULL
MAX(欄位) 最大值
MIN(欄位) 最小值

Day 4:JOIN 多表關聯

-- INNER JOIN:兩邊都有才出現
SELECT e.name, d.dept_name
FROM employees e
INNER JOIN departments d ON e.dept_id = d.id;

-- LEFT JOIN:左表全保留,右表沒對到補 NULL
SELECT e.name, d.dept_name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.id;

-- 實務範例:找出沒有對應部門的員工
SELECT e.name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.id
WHERE d.id IS NULL;
  • JOIN 類型比較
JOIN 類型 結果
INNER JOIN 只保留兩邊都對到的
LEFT JOIN 左表全保留,右表沒對到補 NULL
RIGHT JOIN 右表全保留,左表沒對到補 NULL
FULL OUTER JOIN 兩邊全保留,沒對到的補 NULL
CROSS JOIN 笛卡兒積(所有組合)
  • JOIN 技巧
  • 用別名(alias)簡化:FROM employees e JOIN departments d
  • ON 條件就是「怎麼配對」
  • 一次可以 JOIN 多張表:FROM a JOIN b ON ... JOIN c ON ...

Day 5:新增 / 更新 / 刪除

-- 新增
INSERT INTO employees (name, department, dept_id, salary, hire_date)
VALUES ('新人一號', 'IT', 1, 40000, '2025-01-15');

-- 一次新增多筆
INSERT INTO employees (name, department, dept_id, salary, hire_date) VALUES
('新人二號', 'Sales', 2, 38000, '2025-02-01'),
('新人三號', 'Production', 3, 35000, '2025-02-15');

-- 更新(千萬別漏 WHERE!)
UPDATE employees SET salary = 50000 WHERE id = 10;

-- 更新多欄位
UPDATE employees
SET salary = 55000, department = 'IT'
WHERE id = 5;

-- 刪除(千萬別漏 WHERE!)
DELETE FROM employees WHERE id = 10;
  • 安全習慣(面試必講): 1. UPDATE/DELETE 之前一定先用 SELECT 確認影響範圍 2. 永遠加 WHERE,否則會改/刪「全部」資料 3. 在正式環境先在測試環境驗證 4. 重要操作前先備份 sql -- 先確認要改哪些 SELECT * FROM employees WHERE department = 'IT' AND salary < 40000; -- 確認無誤再改 UPDATE employees SET salary = 42000 WHERE department = 'IT' AND salary < 40000;

  • 子查詢(Subquery)

-- 查薪水高於平均的人
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

-- 查薪水最高的人
SELECT name, salary
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);

-- IN 子查詢:查 IT 或 Sales 部門的人
SELECT name FROM employees
WHERE dept_id IN (SELECT id FROM departments WHERE dept_name IN ('資訊部', '業務部'));

Day 6:30 題實戰演練

  • 自己出或找題庫,涵蓋篩選、排序、分組、JOIN、子查詢
  • 建議題目清單:
# 題目 考點
1 查所有 IT 部門員工 WHERE
2 查薪水前 3 高 ORDER BY + LIMIT
3 查 2024 年後到職的人 WHERE + 日期比較
4 查姓「王」的人 LIKE
5 查薪水在 40000~50000 之間 BETWEEN
6 統計各部門人數 GROUP BY + COUNT
7 各部門平均薪資 GROUP BY + AVG
8 人數超過 2 的部門 HAVING
9 薪水最高的人 MAX 或 ORDER+LIMIT
10 薪水高於平均的人 子查詢
11 IT 部門薪水前 5 高 WHERE + ORDER + LIMIT
12 各部門最高薪 GROUP BY + MAX
13 列出員工與部門名稱 JOIN
14 找沒部門的員工 LEFT JOIN + IS NULL
15 新增一筆員工 INSERT
16 調整某人薪水 UPDATE + WHERE
17 刪除已離職員工 DELETE + WHERE
18 各部門薪資總額 GROUP BY + SUM
19 到職最早的 3 人 ORDER BY + LIMIT
20 統計每年到職人數 日期函數 + GROUP BY
21 薪水排名(不用 RANK) 子查詢
22 同時查多表 多重 JOIN
23 條件更新 UPDATE + 條件
24 查重複資料 GROUP BY + HAVING
25 部門人數佔比 子查詢 + 計算
26 查 NULL 值 IS NULL
27 CASE WHEN 分類 條件表達式
28 組合條件查詢 AND/OR
29 別名與格式化 AS
30 多條件排序 ORDER BY 多欄位
  • 目標:看到題目能直接寫出 SQL

Day 7:複習 + 手寫測驗

  • 不看資料,手寫 5 題: 1. IT 部門薪水前 5 高 2. 各部門平均薪資(只列人數 > 2 的部門) 3. 2024 年後到職的員工與其部門名稱(JOIN) 4. 薪水高於全公司平均的員工 5. 新增一筆員工並更新其薪水
  • 複習執行順序:FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
  • 用自己的話解釋為什麼 WHERE 不能用聚合函數(因為 WHERE 在 GROUP BY 之前執行)

重點觀念速記

執行順序(必背)

FROM       → 決定從哪張表取資料
WHERE      → 篩選列(在分組前)
GROUP BY   → 分組
HAVING     → 篩選組(在分組後)
SELECT     → 決定輸出哪些欄位
ORDER BY   → 排序
LIMIT      → 限制筆數

核心觀念

  • WHERE 篩「列」、HAVING 篩「分組結果」
  • WHERE 不能用聚合函數(因為還沒分組);HAVING 可以
  • UPDATE/DELETE 一定加 WHERE(面試送分題)
  • 改/刪前先用 SELECT 確認範圍
  • 取前 N 名:MySQL/SQLite LIMIT、SQL Server TOP、Oracle FETCH FIRST
  • INNER JOIN:兩邊都有才出現;LEFT JOIN:左表全保留
  • NULL 要用 IS NULL 判斷,不能用 =

面試常考手寫

  • SELECT ... WHERE ... ORDER BY ... LIMIT(基本篩選排序)
  • GROUP BY ... HAVING(分組統計)
  • JOIN ... ON(多表關聯)
  • 子查詢(WHERE 中套 SELECT)

本週實作任務(產出)

任務一:建好測試資料庫

目標:建立兩張有關聯的表,塞入至少 10 筆測試資料。

步驟: 1. 選擇工具:SQLite(離線)或 DB Fiddle(線上) 2. 建立 departments 表(id, dept_name) 3. 建立 employees 表(id, name, department, dept_id, salary, hire_date) 4. 設定 FOREIGN KEY 關聯 5. INSERT 至少 10 筆員工、4 個部門的測試資料 6. 確認 SELECT * 能正確查詢

任務二:30 題查詢練習紀錄

目標:題目 + 你的 SQL + 結果。

格式建議

## 題目 1:查出 IT 部門所有員工
SELECT name, salary FROM employees WHERE department = 'IT';
結果:4 筆(王小明、李小華、陳美麗、周大鵬)

## 題目 2:...

本週重要名詞對照表(中英對照)

中文 英文 說明
結構化查詢語言 SQL (Structured Query Language) 操作關聯式資料庫的語言
查詢 SELECT 讀取資料
篩選 WHERE 條件過濾
排序 ORDER BY 結果排序
分組 GROUP BY 依欄位分組統計
聚合函數 Aggregate Functions COUNT/SUM/AVG/MAX/MIN
關聯 JOIN 連接多張表
內部關聯 INNER JOIN 兩表都有才保留
左外關聯 LEFT JOIN 左表全保留
子查詢 Subquery 查詢中的查詢
主鍵 Primary Key 唯一識別每筆資料
外鍵 Foreign Key 參照其他表的關聯欄位
空值 NULL 表示「沒有值」
別名 Alias (AS) 給欄位/表取暱稱
新增 INSERT 插入新資料
更新 UPDATE 修改既有資料
刪除 DELETE 移除資料
萬用字元 Wildcard (%, _) LIKE 模糊比對用

本週延伸閱讀資源

  1. SQLite Online:https://sqliteonline.com — 免安裝線上練習
  2. DB Fiddle:https://www.db-fiddle.com — 支援多種資料庫語法
  3. W3Schools SQL Tutorial:https://www.w3schools.com/sql — 基礎教學與線上練習
  4. LeetCode SQL 題庫:https://leetcode.com/problemset/database — 進階練習
  5. SQLZoo:https://sqlzoo.net — 互動式 SQL 教學
  6. Mode Analytics SQL Tutorial:較實務導向的 SQL 教學
  7. YouTube: SQL 教學(中文):搜尋「SQL 入門教學」

自我檢核

  • [ ] 我能不看資料手寫 SELECT + WHERE + ORDER BY 查詢
  • [ ] 我能用 GROUP BY 做分組統計並搭配 HAVING
  • [ ] 我能寫 JOIN 關聯兩張表
  • [ ] 我能解釋 INNER JOIN 與 LEFT JOIN 的差異
  • [ ] 我知道 UPDATE/DELETE 一定要加 WHERE(並能說明原因)
  • [ ] 我能說出 SQL 執行順序(FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY)
  • [ ] 我能解釋 WHERE 和 HAVING 的差別
  • [ ] 我能使用子查詢
  • [ ] 我能處理 NULL 值(IS NULL)
  • [ ] 我完成了 30 題 SQL 練習
  • [ ] 我能在面試中 2 分鐘內手寫「IT 部門薪水前 5 高」的 SQL

⬅️ 上一週:第 5 週 | ➡️ 下一週:第 7 週 — Python/VBA 自動化 + 知識管理