以「學生成績管理」資料庫為情境,彙整常用 SQL 查詢語法模式,涵蓋欄位別名、篩選條件、日期處理、彙總函數、分組統計、集合運算、多表連接、子查詢、排序技巧與實務陷阱,供快速查閱與實戰參考。
-- 方式 A:AS 關鍵字
SELECT name AS '姓名' FROM students ORDER BY age;
-- 方式 B:直接指定
SELECT name '姓名' FROM students ORDER BY age;
| 需求 | 語法範例 |
|---|---|
| 列舉值範圍 | `WHERE native IN ('湖南','四川')` |
| 數值區間 | `WHERE age BETWEEN 20 AND 30` |
| 等值比對 | `WHERE name = '李山'` |
| 前綴模糊 | `WHERE name LIKE '李%'` |
| 包含關鍵字 | `WHERE name LIKE '%李%'` |
| 第二字為李 | `WHERE name LIKE '_李%'` |
| 字元集合/範圍 | `WHERE cno LIKE '[AC]%'` 或 `LIKE '[A-C]%'` |
SELECT * FROM students
WHERE birth >= '1980-01-01' AND birth <= '1980-12-31';
直接以字串常數比對,SQL Server 隱含轉換。
-- 單欄分組
SELECT gender, COUNT(sno) FROM students GROUP BY gender;
-- 多重分組
SELECT grade, mno, gender, COUNT(*)
FROM students
GROUP BY grade, mno, gender;
HAVING 過濾群組:
SELECT sno, COUNT(*)
FROM grades
WHERE mark < 60
GROUP BY sno
HAVING COUNT(*) > 1; -- 不及格超過 1 門
SELECT * FROM students WHERE name LIKE '張%'
UNION [ALL]
SELECT * FROM students WHERE name LIKE '李%';
`UNION` 去重,`UNION ALL` 保留重複,效能較佳。
SELECT g.sno, s.name, c.coursename
FROM grades g
JOIN students s ON g.sno = s.sno
JOIN courses c ON g.cno = c.cno;
-- LEFT JOIN 範例:顯示所有課程及修課人數
SELECT courses.cno, MAX(coursename), COUNT(sno)
FROM courses LEFT JOIN grades ON courses.cno = grades.cno
GROUP BY courses.cno;
SELECT c1.cno, c1.coursename, c1.pno, c2.coursename
FROM courses c1, courses c2
WHERE c1.pno = c2.cno;
SELECT lastname + firstname
FROM lastname CROSS JOIN firstname; -- 笛卡兒積
SELECT * FROM students
WHERE native IN (SELECT native FROM students WHERE name = '李山');
SELECT * FROM students
WHERE EXISTS (
SELECT * FROM grades
WHERE grades.sno = students.sno AND cno = 'B2'
);
兩者語意等價,`EXISTS` 在大資料集下常具效能優勢。
| 主題 | 說明 |
|---|---|
| 含空格識別名 | 用 `[]` 括住,如 `[Student Name]` |
| NULL 判斷 | `WHERE mark IS NULL`,不可用 `= NULL` |
| ANY vs ALL | `ANY` 相當 OR 邏輯,`ALL` 相當 AND 邏輯 |
| 否定查詢陷阱 | `WHERE cno <> 'B2'` 仍會回傳有其他課程的學生;正確用 `NOT EXISTS` |
| 多重 NOT EXISTS 模式 | 「選修所有課程的學生」:最外層排除「存在未選修課程」的學生 |
SELECT * FROM students
WHERE NOT EXISTS (
SELECT * FROM courses
WHERE NOT EXISTS (
SELECT * FROM grades
WHERE grades.sno = students.sno
AND grades.cno = courses.cno
)
);
邏輯:找出「不存在任何一門課程是該學生未選修的」學生。
熟練掌握上述語法模式,並理解 `EXISTS`/`NOT EXISTS`、連接類型、子查詢相關性對執行計畫的影響,能撰寫出正確且高效的 SQL 查詢。建議搭配查詢最佳化器圖形化執行計畫驗證實際存取路徑。