HKDSE ICT 卷二A SQL 生存指南
卷二A 資料庫佔主要部分為 SQL。與描述式題目你可能零散失分不同,SQL 是非此即彼的:你的查詢要麼完美運行(滿分)要麼失敗(零分)。好消息是?SQL 是基於模式的。如果你記住這些模式並避免常見陷阱,你可以穩妥地拿到 SQL 分數。
本指南涵蓋 HKDSE ICT 卷二A 測試的所有 SQL 模式——子句順序、篩選、連接、資料定義和考試題型。掌握這些,練習鑽研計劃,SQL 就成為你的拿分科目。
黃金法則:子句順序至關重要
SQL 子句必須按嚴格順序出現。弄錯這個會讓你整題丟分,即使你的邏輯是正確的。
記住這個順序:
SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY
實例 —— 學生與成績架構:
-- 找出平均分 >= 80 的學生,按平均分降序排列
SELECT StudentName, AVG(Mark) as AvgMark
FROM Students
INNER JOIN Marks ON Students.StudentID = Marks.StudentID
WHERE Mark IS NOT NULL
GROUP BY StudentID, StudentName
HAVING AVG(Mark) >= 80
ORDER BY AvgMark DESC;
為什麼是這個順序:
SELECT—— 你想要輸出什麼FROM—— 你要查詢哪些表WHERE—— 分組前篩選行(個別記錄)GROUP BY—— 為聚合函數分組行(COUNT、AVG、SUM、MAX、MIN)HAVING—— 分組後篩選組(組級條件)ORDER BY—— 排序最終結果
考試陷阱:不要把 WHERE 放在 GROUP BY 之後。不要把 HAVING 放在 GROUP BY 之前。不要在 WHERE 中使用聚合函數(如 AVG(Mark))—— 那應該放在 HAVING 中。一個子句位置錯誤 = 零分。
WHERE vs HAVING:篩選分界線
這是卷二A 最常見的 SQL 錯誤。區別很簡單但關鍵:
WHERE 在分組前篩選個別行。 HAVING 在分組後篩選組。
對比這兩個查詢:
-- WHERE:分組前篩選行
SELECT StudentID, COUNT(*) as PaperCount
FROM Marks
WHERE Mark >= 50 -- 只計算 >= 50 的試卷
GROUP BY StudentID;
-- HAVING:分組後篩選組
SELECT StudentID, AVG(Mark) as AvgMark
FROM Marks
GROUP BY StudentID
HAVING AVG(Mark) >= 50; -- 只顯示平均分 >= 50 的學生
第一個查詢:計算每個學生 >= 50 的試卷數。成績 [40, 60, 80] 的學生計算 2 張試卷(60 和 80)。
第二個查詢:計算完整平均分,然後篩選。同樣成績 [40, 60, 80] 的學生平均分是 60,所以被包括。
考試模式:如果條件涉及個別記錄(如 Mark >= 50),使用 WHERE。如果條件涉及聚合(如 AVG(Mark) >= 50 或 COUNT(*) > 3),使用 HAVING。
JOIN 連接:INNER vs LEFT
JOIN 通過主鍵/外鍵關係組合多個表的資料。卷二A 測試兩種連接類型:
鍵值提醒:
- 主鍵 (PK):每條記錄的唯一識別符(如 Students 表中的
StudentID) - 外鍵 (FK):引用另一個表的主鍵(如 Marks 表中的
StudentID)
INNER JOIN —— 僅兩個表的匹配記錄:
SELECT Students.StudentName, Marks.Mark
FROM Students
INNER JOIN Marks ON Students.StudentID = Marks.StudentID;
結果:只有有成績的學生。如果學生沒有成績記錄,他們不會出現。
LEFT JOIN —— 左表所有記錄 + 右表匹配記錄(無匹配則為 NULL):
SELECT Students.StudentName, Marks.Mark
FROM Students
LEFT JOIN Marks ON Students.StudentID = Marks.StudentID;
結果:所有學生,包括沒有成績的學生。沒有成績的學生顯示 Mark 為 NULL。
何時使用哪個:
- 需要僅有匹配的記錄(如參加考試的學生)? →
INNER JOIN - 需要所有來自一個表的記錄無論是否有匹配(如所有學生,包括未參加考試的)? →
LEFT JOIN
考試提示:在卷二A 中,大多數查詢使用 INNER JOIN。當題目明確要求「所有學生包括沒有…」或「列出所有 X 即使沒有 Y 存在」時,才會出現 LEFT JOIN。
DDL vs DML:定義 vs 操作資料
SQL 命令分為兩類:
DDL (資料定義語言) —— 定義資料庫結構:
CREATE TABLE—— 創建新表ALTER TABLE—— 修改表結構(添加/刪除欄位)DROP TABLE—— 刪除整個表(結構 + 資料)
DML (資料操作語言) —— 操作表內的資料:
INSERT INTO—— 添加新記錄UPDATE—— 修改現有記錄DELETE FROM—— 刪除記錄
DROP vs DELETE vs TRUNCATE(經常比較):
| 命令 | 刪除內容 | 速度 | 可回滾 |
|---|---|---|---|
DROP TABLE Marks | 表結構 + 所有資料 | 快 | 不可 (DDL) |
DELETE FROM Marks | 所有行(表保留) | 慢(逐行) | 可 (DML) |
DELETE FROM Marks WHERE Mark < 50 | 特定行 | 慢 | 可 |
TRUNCATE TABLE Marks | 所有行(表保留) | 快 | 不可 (DDL) |
考試模式:你可能被要求「寫一個 SQL 命令刪除所有低於 50 的成績」 → DELETE FROM Marks WHERE Mark < 50。或「完全刪除 Marks 表」 → DROP TABLE Marks。
鍵值回顧:基礎
在寫 JOIN 之前,你必須理解鍵:
主鍵 (PK):
- 唯一識別每條記錄
- 不能為 NULL,不能重複
- 從不改變(穩定識別符)
外鍵 (FK):
- 引用另一個表的主鍵
- 強制引用完整性
- 可以為 NULL(可選關係)
候選鍵:
- 可作為主鍵
- 最小超鍵
複合鍵:
- 兩個或更多欄位一起形成唯一識別符
- 示例:
(StudentID, CourseID)作為選課表的主鍵
示例:
CREATE TABLE Students (
StudentID INT PRIMARY KEY, -- PK
StudentName VARCHAR(50),
ClassID INT, -- FK 到 Classes 表
FOREIGN KEY (ClassID) REFERENCES Classes(ClassID)
);
考試題型模式
卷二A SQL 題目遵循三種原型。識別模式,應用模板:
1. 從英文規範寫查詢(最常見)
轉述示例:「寫一個 SQL 查詢找出至少在一份試卷中得分超過 80 的學生姓名,按姓名排序。」
模式識別:
- 「找出姓名」 →
SELECT StudentName - 「得分超過 80 的學生」 →
WHERE Mark > 80 - 「至少一份試卷」 → 只需
WHERE,無需分組 - 「按姓名排序」 →
ORDER BY StudentName
解答:
SELECT DISTINCT s.StudentName
FROM Students s
INNER JOIN Marks m ON s.StudentID = m.StudentID
WHERE m.Mark > 80
ORDER BY s.StudentName;
2. 找出查詢中的錯誤
轉述示例:「以下 SQL 查詢應該找出平均分高於 70 的學生,但包含錯誤。識別並修正它。」
-- 錯誤查詢
SELECT StudentName, AVG(Mark) as AvgMark
FROM Students
INNER JOIN Marks ON Students.StudentID = Marks.StudentID
WHERE AVG(Mark) > 70 -- 錯誤:WHERE 中的聚合
GROUP BY StudentID;
錯誤:不能在 WHERE 子句中使用聚合函數 AVG(Mark)。
修正:將聚合條件移到 HAVING 子句。
3. 給定查詢的輸出
轉述示例:「給定以下的 Students 和 Marks 表,以下查詢的輸出是什麼?」
對於此模式,你逐步追蹤查詢:應用篩選、執行連接、計算聚合、排序結果。在小架構上(每個表 3-4 條記錄)練習追蹤。
20 題鑽研計劃
通過這個進度建立肌肉記憶。從單表 SELECT 開始,進階到分組連接。
第 1 週:基礎(查詢 1-8)
SELECT * FROM StudentsSELECT StudentName FROM Students WHERE Class = '6A'SELECT StudentName FROM Students WHERE StudentName LIKE 'Chan%'SELECT * FROM Marks WHERE Mark BETWEEN 60 AND 80SELECT * FROM Marks WHERE Mark IS NULLSELECT COUNT(*) FROM MarksSELECT AVG(Mark) FROM Marks WHERE Subject = 'ICT'SELECT StudentName, Mark FROM Students INNER JOIN Marks ON Students.StudentID = Marks.StudentID
第 2 週:分組與聚合(查詢 9-14)
9. SELECT StudentID, AVG(Mark) FROM Marks GROUP BY StudentID
10. SELECT StudentID, COUNT(*) FROM Marks GROUP BY StudentID HAVING COUNT(*) > 2
11. SELECT Subject, AVG(Mark) FROM Marks GROUP BY Subject ORDER BY AVG(Mark) DESC
12. SELECT Class, COUNT(*) FROM Students GROUP BY Class
13. SELECT StudentID, SUM(Mark) FROM Marks WHERE Mark >= 50 GROUP BY StudentID
14. SELECT Subject, MAX(Mark), MIN(Mark) FROM Marks GROUP BY Subject
第 3 週:連接與篩選(查詢 15-20)
15. SELECT s.StudentName, m.Mark FROM Students s INNER JOIN Marks m ON s.StudentID = m.StudentID WHERE m.Mark > 70
16. SELECT s.StudentName, AVG(m.Mark) FROM Students s INNER JOIN Marks m ON s.StudentID = m.StudentID GROUP BY s.StudentID HAVING AVG(m.Mark) >= 60
17. SELECT s.StudentName, m.Mark FROM Students s LEFT JOIN Marks m ON s.StudentID = m.StudentID
18. SELECT c.ClassName, COUNT(s.StudentID) FROM Classes c LEFT JOIN Students s ON c.ClassID = s.ClassID GROUP BY c.ClassName
19. SELECT s.StudentName, m.Subject, m.Mark FROM Students s INNER JOIN Marks m ON s.StudentID = m.StudentID WHERE m.Subject = 'ICT' AND m.Mark >= 50 ORDER BY m.Mark DESC
20. SELECT s.ClassName, AVG(m.Mark) FROM Students s INNER JOIN Marks m ON s.StudentID = m.StudentID GROUP BY s.ClassName HAVING AVG(m.Mark) > 70 ORDER BY AVG(m.Mark) DESC
練習常規:在不查看筆記的情況下記憶每個查詢。與樣本解答對比。重寫失敗的查詢,直到你能連續三次正確寫出。
最終考試策略
當你打開卷二A 時:
- 先讀架構 —— 在寫任何查詢之前,識別 PK、FK 和表關係。
- 解析英文 —— 劃線標出你要選擇、篩選、分組和排序的內容。
- 寫子句順序骨架 ——
SELECT ___ FROM ___ WHERE ___ GROUP BY ___ HAVING ___ ORDER BY ___(邊做邊填空) - 雙重檢查聚合位置 ——
WHERE中有任何COUNT、AVG、SUM、MAX、MIN?移到HAVING。 - 驗證 JOIN 邏輯 —— 你需要所有記錄(
LEFT)還是僅匹配記錄(INNER)? - 心智追蹤 —— 對於「給定查詢的輸出」題目,手動追蹤 2-3 條記錄以確認你的答案。
SQL 獎勵精確性。記住模式,避免陷阱,練習直到子句順序變成自動。你可以在卷二A 中拿到完整的 SQL 分數 —— 本指南給你提供路線圖。
想要你的 SQL 查詢的反饋? 預約一節課 —— 我們會一起審查你的練習查詢,修正你的錯誤,在考試前建立你的信心。查看我們的 HKDSE ICT 完整指南 獲取包括所有選修科的完整科目路線圖。