跳轉至

建立 2026-11-12 更新 2026-11-12 SL HL

A3.3 資料庫程式設計 SQL

SQL(Structured Query Language,結構化查詢語言)是查詢與操作關聯式資料庫的標準語言。本頁用一個學校資料庫範例,依序說明查詢、篩選、排序、聚合、多表 JOIN,以及新增、修改、刪除資料與建立資料表的指令。

範例資料庫

Student(studentID, name, grade, house)
Course(courseID, title, level)          -- level 為 'SL' 或 'HL'
Enrollment(studentID, courseID, score)

如何查詢資料?

SELECT 指定欄位,FROM 指定資料表,WHERE 篩選列,ORDER BY 排序:

SELECT name, grade
FROM Student
WHERE grade = 11 AND house = 'Red'
ORDER BY name ASC;

常用篩選條件:

語法 意義 例子
=, <>, >, <= 比較 score >= 6
AND, OR, NOT 邏輯組合 grade = 11 OR grade = 12
BETWEEN a AND b 範圍(含兩端) score BETWEEN 4 AND 6
IN (...) 屬於清單之一 house IN ('Red', 'Blue')
LIKE 模式比對,% 代表任意字串、_ 代表一個字元 name LIKE 'A%'
IS NULL 欄位為空 score IS NULL

如何做統計?

聚合函式(aggregate function)把多列計算成一個值:COUNT、SUM、AVG、MIN、MAX。GROUP BY 分組計算,HAVING 篩選分組後的結果:

-- 每門課的平均分數,只列出平均大於 5 的課
SELECT courseID, AVG(score) AS avgScore, COUNT(*) AS students
FROM Enrollment
GROUP BY courseID
HAVING AVG(score) > 5
ORDER BY avgScore DESC;

WHERE 與 HAVING 的差別

WHERE 在分組 之前 篩選個別列;HAVING 在分組 之後 篩選群組,所以聚合函式條件只能寫在 HAVING。

如何查詢多張資料表?

JOIN 依外鍵把多張表合併。INNER JOIN 只保留兩邊都有對應的列:

-- 列出所有修 HL 課程學生的姓名、課名與分數
SELECT s.name, c.title, e.score
FROM Student s
INNER JOIN Enrollment e ON s.studentID = e.studentID
INNER JOIN Course c     ON e.courseID  = c.courseID
WHERE c.level = 'HL'
ORDER BY e.score DESC;

LEFT JOIN 保留左表所有列,右表沒有對應時填 NULL,可用來找「沒有修任何課的學生」:

SELECT s.name
FROM Student s
LEFT JOIN Enrollment e ON s.studentID = e.studentID
WHERE e.courseID IS NULL;

如何新增、修改與刪除資料?

INSERT INTO Student (studentID, name, grade, house)
VALUES (101, 'Chris', 11, 'Blue');

UPDATE Enrollment
SET score = 7
WHERE studentID = 101 AND courseID = 'CS-HL';

DELETE FROM Enrollment
WHERE studentID = 101;

UPDATE 與 DELETE 一定要寫 WHERE

少了 WHERE,UPDATE 會修改整張表的每一列,DELETE 會刪除整張表的所有資料。

如何建立資料表?

資料定義語言(Data Definition Language, DDL)用來建立與修改結構;上面的查詢與修改屬於資料操作語言(Data Manipulation Language, DML)。

CREATE TABLE Enrollment (
    studentID INTEGER NOT NULL,
    courseID  VARCHAR(10) NOT NULL,
    score     INTEGER CHECK (score BETWEEN 1 AND 7),
    PRIMARY KEY (studentID, courseID),
    FOREIGN KEY (studentID) REFERENCES Student(studentID),
    FOREIGN KEY (courseID)  REFERENCES Course(courseID)
);

什麼是檢視表?

檢視表(view)是存起來的查詢,使用起來像一張虛擬資料表,可以簡化常用查詢,並只讓使用者看到部分欄位(例如不讓助教看到學生電話)。

CREATE VIEW HLStudents AS
SELECT s.studentID, s.name, c.title
FROM Student s
JOIN Enrollment e ON s.studentID = e.studentID
JOIN Course c     ON e.courseID  = c.courseID
WHERE c.level = 'HL';

如何在程式中執行 SQL?

IA 與實際應用中,常用程式語言連接資料庫。以 Python 內建的 sqlite3 為例,一定要用參數化查詢(? 佔位符),避免 SQL 注入:

import sqlite3

conn = sqlite3.connect("school.db")
cur = conn.cursor()

name = input("學生姓名:")
cur.execute("SELECT studentID, grade FROM Student WHERE name = ?", (name,))
for student_id, grade in cur.fetchall():
    print(student_id, grade)

conn.close()

推薦影音

SQL 入門完整課程(Programming with Mosh)

簡述:Mosh 以實際資料庫示範 SELECT、WHERE、JOIN、GROUP BY、子查詢等指令,節奏清楚,可以邊看邊在 SQLite 或 MySQL 上練習。

SQL 完整資料庫課程(freeCodeCamp)

簡述:freeCodeCamp 的長篇課程,從資料庫概念、建表、查詢一路講到 ER 圖設計,適合想系統化學習或準備 IA 的學生。

練習題

以下題目都使用本頁的範例資料庫。

練習 1:基本查詢

列出所有 12 年級學生的姓名,依姓名字母排序。

參考答案
SELECT name
FROM Student
WHERE grade = 12
ORDER BY name;
練習 2:聚合

計算每個 house 的學生人數,只顯示人數超過 20 人的 house。

參考答案
SELECT house, COUNT(*) AS total
FROM Student
GROUP BY house
HAVING COUNT(*) > 20;
練習 3:JOIN

列出修讀課名為 Computer Science 的所有學生姓名與分數,分數高的排前面。

參考答案
SELECT s.name, e.score
FROM Student s
JOIN Enrollment e ON s.studentID = e.studentID
JOIN Course c     ON e.courseID  = c.courseID
WHERE c.title = 'Computer Science'
ORDER BY e.score DESC;
練習 4:修改資料

學生 205 從 Green house 換到 Yellow house,寫出 SQL。

參考答案
UPDATE Student
SET house = 'Yellow'
WHERE studentID = 205;
練習 5:找出錯誤

下列查詢有什麼問題?SELECT courseID, AVG(score) FROM Enrollment WHERE AVG(score) > 5 GROUP BY courseID;

參考答案

聚合函式不能用在 WHERE,因為 WHERE 在分組前執行。應改為 GROUP BY courseID HAVING AVG(score) > 5。