章节笔记:掌握 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)。实践是关键,所以试着为不同的情景编写你自己的查询吧。做得好!