章節筆記:掌握 SQL(結構化查詢語言)
各位同學好!歡迎來到資料庫的世界。試想想你身邊所有的資料:朋友的聯絡資料、學校的學生紀錄、網上購物網站上的商品等等。所有這些資訊是如何儲存、管理和檢索的呢?答案往往是一個資料庫,而我們用來與它「溝通」的語言就是 SQL。
在這些筆記中,我們將學習如何使用 SQL 來提出問題、更改資訊,甚至建立資料庫的一部分。這就像學習一種秘密語言,它為你每天使用的許多應用程式和網站提供支援。剛開始時可能覺得有點難,但別擔心,我們會透過大量例子一步步地將它拆解!
什麼是 SQL?一個簡單的比喻
想像一下你學校的圖書館有一個超級有條理的數碼目錄。SQL 就是你用來要求圖書館管理員(資料庫管理系統,或稱 DBMS)在該目錄(資料庫)中尋找、新增或更新書籍資訊的特殊語言。
- 查詢資料:「顯示所有 J.K. Rowling 撰寫的書籍。」
- 新增資料:「將這本新書《資訊及通訊科技歷險記》新增到系統中。」
- 更新資料:「將《哈利波特》的狀態從『可借閱』更改為『已借出』。」
SQL 有幾種主要的指令類型。我們可以把它們想像成不同類型的請求:
- 資料查詢語言 (DQL):用於提出問題和獲取資料。(最常用!)
- 資料操作語言 (DML):用於更改資料(新增、更新、刪除記錄)。
- 資料定義語言 (DDL):用於建立和管理資料庫結構本身(建立或更改表格)。
第一部分:使用 SELECT 查詢資料 (DQL)
這是 SQL 中最重要且最常用的部分,它全部關於檢索資訊。其基本結構簡單易記。
我們將使用一個名為 Students 的範例表格作為例子:
Students 表格
學生編號 | 名字 | 姓氏 | 班級 | 分數
101 | Chan | Tai Man | 5A | 88
102 | Lee | Siu Ming | 5B | 95
103 | Wong | Ka Wai | 5A | 72
104 | Ng | Mei Ling | 5C | 88
105 | Cheung | Pui Sze | 5B | 65
基本 SELECT 語句
兩個必要的部分是 SELECT(你想要哪些欄位)和 FROM(從哪個表格中查找)。
獲取指定欄位:
查找所有學生的名字和姓氏。
SELECT FirstName, LastName FROM Students;
獲取所有欄位(使用萬用字元 *):
查找所有學生的所有資訊。
SELECT * FROM Students;
記憶小貼士:將 * 想像成一個萬用字元,意思是「所有」。
使用 WHERE 過濾結果
如果你不想獲取所有記錄怎麼辦?WHERE 子句允許你設定條件來過濾結果。
查找 5A 班學生的名字。
SELECT FirstName, LastName FROM Students WHERE Class = '5A';
重要提示:文字值(如 '5A')通常放在單引號 ' '
內。
WHERE 子句的運算子
你可以使用不同的運算子來建立強大的篩選條件:
- 比較運算子:
=
(等於)<>
(不等於)>
(大於)<
(小於)>=
(大於或等於)<=
(小於或等於)
- 邏輯運算子:
- AND:兩個條件都必須為真。(例如:
WHERE Class = '5A' AND Score > 80
) - OR:至少一個條件必須為真。(例如:
WHERE Score < 70 OR Score > 90
) - NOT:反轉條件的結果。(例如:
WHERE NOT Class = '5A'
)
- AND:兩個條件都必須為真。(例如:
- 特殊運算子:
- BETWEEN:檢查值是否在指定範圍內(包含兩端)。
例子:WHERE Score BETWEEN 70 AND 90;
(這等同於Score >= 70 AND Score <= 90
) - IN:檢查值是否與列表中任何值匹配。
例子:WHERE Class IN ('5A', '5C');
(這是Class = '5A' OR Class = '5C'
的簡寫) - LIKE:用於文字的模式匹配。它使用萬用字元:
%
:代表零個、一個或多個字元。_
:代表一個單一字元。
WHERE LastName LIKE 'W%';
例子 2:查找名字是 'Siu' 後面跟著四個字元的學生。WHERE FirstName LIKE 'Siu ____';
- BETWEEN:檢查值是否在指定範圍內(包含兩端)。
使用 ORDER BY 排序結果
ORDER BY 子句會對你的結果進行排序。預設情況下,它按升序排序(A-Z,1-100)。
- ASC:升序(預設值)。
- DESC:降序。
列出所有學生,按分數從高到低排序。
SELECT FirstName, LastName, Score FROM Students ORDER BY Score DESC;
快速回顧:DQL 黃金三劍客
對於大多數查詢,你會使用這個結構:
SELECT [欄位]
FROM [表格]
WHERE [條件]
ORDER BY [排序欄位];
你不一定總是需要 `WHERE` 或 `ORDER BY`,但它們必須按這個順序出現!
第二部分:匯總及操作資料(選修內容)
現在我們將進入資料庫選修部分涵蓋的更進階主題。這正是 SQL 變得真正強大的地方!
聚合函數:全盤概覽
這些函數對一組行執行計算,並返回一個單一的匯總值。
- COUNT():計算行數。
- SUM():計算欄位中所有值的總和。
- AVG():計算欄位中值的平均值。
- MAX():查找欄位中的最高值。
- MIN():查找欄位中的最低值。
總共有多少學生?
SELECT COUNT(*) FROM Students;
5A 班學生的平均分數是多少?
SELECT AVG(Score) FROM Students WHERE Class = '5A';
字串函數:處理文字
SQL 有用於處理文字資料的函數。確切的名稱可能有所不同,但概念是相似的。
- LENGTH() 或 LEN():獲取字串的字元數。
- UCASE() 或 UPPER():將文字轉換為大寫。
- LCASE() 或 LOWER():將文字轉換為小寫。
顯示所有學生姓氏的大寫形式。
SELECT UCASE(LastName) FROM Students;
使用 DML 更改資料
這些指令修改表格內部的資料。
注意! DML 的一個錯誤可能會永久性地更改或刪除你的資料。使用 WHERE 子句時務必小心!
INSERT INTO:新增資料
向表格新增一行(記錄)。
向表格新增一個學生。
INSERT INTO Students (StudentID, FirstName, LastName, Class, Score) VALUES (106, 'Lau', 'Kit Ying', '5C', 81);
UPDATE:修改現有資料
更改現有行中的資料。
常見錯誤:忘記 `WHERE` 子句將更新表格中的所有行!
Chan Tai Man(學生編號 101)重考了一次,現在他的分數是 91。
UPDATE Students SET Score = 91 WHERE StudentID = 101;
DELETE:刪除資料
從表格中刪除行。
常見錯誤:忘記 `WHERE` 子句將刪除表格中的所有行!
學生 Cheung Pui Sze(學生編號 105)已離校。
DELETE FROM Students WHERE StudentID = 105;
重點:DML 的安全使用
WHERE 子句是 UPDATE 和 DELETE 的安全網。它告訴資料庫確切要更改或刪除哪條記錄。在執行指令前務必仔細檢查!
第三部分:使用連接及子查詢進行進階查詢(選修內容)
真實世界的資料庫為了提高效率,會將資料分散儲存於多個表格中。我們如何將它們組合起來呢?使用連接 (JOINs)!
讓我們新增另一個表格:Courses。
Courses 表格
課程編號 | 課程名稱 | 教師
ICT | 資訊科技 | 李先生
ENG | 英文 | 戴維斯女士
MATH| 數學 | 陳太太
前提知識:主鍵與外來鍵
為了連接表格,我們需要特殊的鍵。
- 主鍵 (PK) 是表格中唯一識別每條記錄的欄位(例如 Students 表格中的 `StudentID`)。
- 外來鍵 (FK) 是來自一個表格的主鍵,你將其放入另一個表格中以建立連接。
連接表格
連接 (JOIN) 根據表格之間相關的欄位將兩個或多個表格中的行組合起來。
等值連接(或稱內部連接 INNER JOIN)
這是最常見的連接類型。它只返回在兩個表格中都有匹配值的記錄。
讓我們想像我們有第三個表格 Enrollments,它連接 Students 和 Courses。
Enrollments 表格
學生編號 | 課程編號
101 | ICT
101 | ENG
102 | ICT
103 | MATH
顯示每個學生的名字以及他們報讀的課程名稱。
SELECT S.FirstName, C.CourseName
FROM Students S JOIN Enrollments E ON S.StudentID = E.StudentID
JOIN Courses C ON E.CourseID = C.CourseID;
解釋:
1. 我們使用別名(S 代表 Students,C 代表 Courses)來縮短程式碼。
2. ON 關鍵字指定連接條件:`ON table1.column = table2.column`。
外部連接(左連接 LEFT JOIN 和右連接 RIGHT JOIN)
如果你想查看一個表格中的所有記錄,即使它們在另一個表格中沒有匹配項,該怎麼辦?
- LEFT JOIN(左連接):返回左側表格(首先提到的表格)中的所有記錄,以及右側表格中匹配的記錄。如果沒有匹配項,右側結果為空值 (NULL)。
- RIGHT JOIN(右連接):返回右側表格中的所有記錄。它與左連接相反。
列出所有學生及其所修讀的課程。即使沒有修讀任何課程的學生也應列出。
SELECT S.FirstName, E.CourseID
FROM Students S LEFT JOIN Enrollments E ON S.StudentID = E.StudentID;
這將顯示 Chan Tai Man 和 Lee Siu Ming 及其課程,但 Wong Ka Wai、Ng Mei Ling 等也會被列出,其 `CourseID` 為空值 (NULL),因為它們在左側表格(Students)中,但在 Enrollments 表格中沒有匹配項。
自然連接 (Natural Join)
NATURAL JOIN(自然連接)是一種等值連接,資料庫會根據具有相同名稱的欄位自動連接表格。它很方便,但如果表格有多個同名欄位,可能會產生不可預測的結果。
(在我們的例子中,為了使用它,我們需要將兩個表格中的欄位都重命名為 `StudentID`)。
SELECT FirstName, CourseID FROM Students NATURAL JOIN Enrollments;
子查詢(單層)
子查詢是嵌套在另一個查詢中的查詢。內部查詢的結果被外部查詢使用。
查找分數高於班級平均分的學生姓名。
SELECT FirstName, LastName
FROM Students
WHERE Score > (SELECT AVG(Score) FROM Students);
逐步解釋:
1. 內部查詢 (SELECT AVG(Score) FROM Students)
首先執行,並計算平均分數(例如 82)。
2. 然後外部查詢執行為:SELECT FirstName, LastName FROM Students WHERE Score > 82;
重點:組合資料
連接 (JOINs) 用於組合來自不同表格的欄位。子查詢 用於將一個查詢的結果作為另一個查詢的條件。
第四部分:檢視表和表格結構(選修內容)
建立檢視表 (VIEW)
檢視表 (VIEW) 是基於 SQL 語句結果集的一個虛擬表格。它就像一個已儲存的查詢,你可以像操作真實表格一樣與它互動。檢視表對於以下方面很有用:
- 簡化複雜的查詢。
- 透過只顯示某些欄位或行來提供一層安全性。
建立一個只顯示 5A 班學生的檢視表。
CREATE VIEW Class5A_Students AS
SELECT StudentID, FirstName, LastName, Score
FROM Students
WHERE Class = '5A';
現在,你可以直接查詢這個檢視表:
SELECT * FROM Class5A_Students;
使用 DDL 修改表格結構
有時候你需要更改表格建立後的結構(即「模式」)。我們使用 ALTER TABLE 來實現這一點。
- ADD Column:向表格新增一個欄位。
- DROP COLUMN:移除一個欄位。
- MODIFY COLUMN 或 ALTER COLUMN:更改欄位的資料類型。
向 Students 表格新增一個名為 'Email' 的新欄位。
ALTER TABLE Students ADD Email VARCHAR(255);
(VARCHAR 是一種常用的可變長度文字資料類型)。
移除我們剛剛新增的 'Email' 欄位。
ALTER TABLE Students DROP COLUMN Email;
你知道嗎?
SQL 最初於 1970 年代初由 IBM 開發。它最初的名字是 SEQUEL(結構化英文查詢語言)。儘管它已有將近 50 年的歷史,但它仍然是全球科技職位中最受歡迎的技能之一!
最後總結
你已經學會了 SQL 的基礎知識!從簡單的 SELECT...FROM...WHERE 查詢到複雜的資料操作和多表格連接 (JOINs)。實踐是關鍵,所以試著為不同的情景編寫你自己的查詢吧。做得好!