跳到主内容
Zhimalab
第 1 课 / 共 21 课

认识 SQL

数据库与 SQL 是什么

数据库是按结构组织的数据集合,MySQL 是最流行的关系型数据库之一。

SQL(Structured Query Language)是操作数据库的标准语言,本教程涵盖查询、插入、更新、删除等核心操作。

💡
本教程在浏览器中模拟运行 SQL,无需安装。点击代码块中的「运行」按钮即可查看结果。

先看看数据库里有哪些表:

SQL
SHOW TABLES;

查看 students 表的结构:

SQL
DESC students;
小测
SQL 的全称是?
A Structured Query Language
B Simple Query Language
C Standard Question Language
D System Query Logic
第 2 课 / 共 21 课

SELECT 基础

从表中查询数据

SELECT 用于从表中查询数据,* 表示所有列。

SQL
SELECT * FROM students;

也可以指定列名,用逗号分隔:

SQL
SELECT name, age, gender FROM students;
小测
查询所有列用哪个符号?
A *
B #
C %
D &
第 3 课 / 共 21 课

WHERE 条件过滤

按条件筛选行

WHERE 子句用于筛选满足条件的行。

SQL
SELECT * FROM students WHERE age > 20;

支持的比较运算符:= > < >= <= <> !=

SQL
SELECT * FROM students WHERE gender = '';

AND / OR 组合多个条件:

SQL
SELECT * FROM students WHERE age >= 20 AND gender = '';
小测
查询年龄不等于 20 的学生,条件应写?
A WHERE age = 20
B WHERE age NOT 20
C WHERE age <> 20
D WHERE age IS NOT 20
第 4 课 / 共 21 课

ORDER BY 排序

对结果排序

ORDER BY 按列排序,ASC 升序(默认),DESC 降序。

SQL
SELECT * FROM students ORDER BY age DESC;

可按多列排序,优先级从左到右:

SQL
SELECT * FROM students ORDER BY dept_id ASC, age DESC;
小测
不指定排序方向时默认是?
A ASC 升序
B DESC 降序
C 随机
D 按主键
第 5 课 / 共 21 课

LIMIT 分页

限制返回行数

LIMIT 限制返回的行数,常用于分页。

SQL
SELECT * FROM students LIMIT 3;

LIMIT 偏移量, 数量 实现分页查询:

SQL
SELECT * FROM students LIMIT 2, 3;
小测
查询第 4-6 条数据(每页 3 条),LIMIT 写?
A LIMIT 4, 3
B LIMIT 3, 3
C LIMIT 3, 6
D LIMIT 6, 3
第 6 课 / 共 21 课

聚合函数

COUNT SUM AVG MAX MIN

聚合函数对一组值计算,返回单个值。

SQL
SELECT COUNT(*) FROM students;
SQL
SELECT AVG(age) FROM students;
SQL
SELECT MAX(score), MIN(score) FROM enrollments;
COUNT(*) 统计行数,AVG 求平均,SUM 求和,MAX/MIN 求极值。
小测
统计学生总数用哪个函数?
A COUNT(*)
B SUM(*)
C COUNT(ALL)
D TOTAL(*)
第 7 课 / 共 21 课

GROUP BY 分组

按列分组统计

GROUP BY 按列分组,常与聚合函数配合使用。

SQL
SELECT dept_id, COUNT(*) FROM students GROUP BY dept_id;
SQL
SELECT gender, AVG(age) FROM students GROUP BY gender;
小测
按院系统计学生人数,GROUP BY 写?
A GROUP BY dept_id
B GROUP BY COUNT
C GROUP dept_id
D SPLIT BY dept_id
第 8 课 / 共 21 课

HAVING 分组过滤

过滤分组后的结果

HAVING 用于过滤分组后的结果,相当于分组后的 WHERE。

SQL
SELECT dept_id, COUNT(*) AS cnt FROM students GROUP BY dept_id HAVING cnt > 2;
⚠️
WHERE 在分组前过滤行,HAVING 在分组后过滤组。聚合条件只能用 HAVING。
小测
下列哪个关键字用于分组后的条件过滤?
A WHERE
B HAVING
C LIMIT
D ORDER BY
第 9 课 / 共 21 课

DISTINCT 去重

消除重复行

DISTINCT 去除查询结果中的重复行。

SQL
SELECT DISTINCT gender FROM students;
SQL
SELECT DISTINCT dept_id, gender FROM students;
小测
查询不重复的年龄值,正确写法?
A SELECT DISTINCT age FROM students
B SELECT UNIQUE age FROM students
C SELECT age DISTINCT FROM students
D SELECT DIFFERENT age FROM students
第 10 课 / 共 21 课

INSERT 插入数据

向表中添加行

INSERT INTO 向表中插入数据。

SQL
INSERT INTO students (name, gender, age, dept_id, enroll_year) VALUES ('测试同学', '', 20, 1, 2024);

插入后查询验证:

SQL
SELECT * FROM students ORDER BY id DESC LIMIT 1;
小测
插入数据用的语句是?
A INSERT INTO
B ADD INTO
C INSERT TO
D PUT INTO
第 11 课 / 共 21 课

UPDATE 更新数据

修改已有行

UPDATE 修改满足条件的行。

SQL
UPDATE students SET age = 21 WHERE name = '赵小明';
⚠️
不加 WHERE 会更新所有行!请务必谨慎。
小测
更新所有行的 age 为 20,正确写法?
A UPDATE students SET age = 20 IF ALL
B UPDATE students SET age = 20
C UPDATE students ALL SET age = 20
D UPDATE ALL students SET age = 20
第 12 课 / 共 21 课

DELETE 删除数据

删除行

DELETE 删除满足条件的行。

SQL
DELETE FROM students WHERE name = '测试同学';
⚠️
不加 WHERE 会清空全表数据!
小测
删除 age 大于 22 的行,正确写法?
A DELETE FROM students WHERE age > 22
B DELETE students WHERE age > 22
C REMOVE FROM students WHERE age > 22
D DROP FROM students WHERE age > 22
第 13 课 / 共 21 课

建表与删表

CREATE TABLE 与 DROP TABLE

CREATE TABLE 创建新表,需定义列名和类型。

SQL
CREATE TABLE clubs (id INT, name VARCHAR, leader VARCHAR);

查看刚创建的表:

SQL
DESC clubs;

DROP TABLE 删除整张表(结构连同数据):

SQL
DROP TABLE clubs;
小测
删除整张表(含结构)用哪个语句?
A DELETE TABLE
B DROP TABLE
C REMOVE TABLE
D CLEAR TABLE
第 14 课 / 共 21 课

INNER JOIN 内连接

关联多表数据

INNER JOIN 根据关联条件合并两表,只返回两表都匹配的行。

SQL
SELECT students.name, departments.name AS dept FROM students INNER JOIN departments ON students.dept_id = departments.id;

使用表别名简化书写:

SQL
SELECT s.name, d.name AS dept FROM students s INNER JOIN departments d ON s.dept_id = d.id LIMIT 5;
小测
连接两表的关联条件用哪个关键字?
A ON
B WHERE
C BY
D WITH
第 15 课 / 共 21 课

LEFT JOIN 左连接

保留左表所有行

LEFT JOIN 保留左表所有行,右表无匹配时填充 NULL。

SQL
SELECT t.name, d.name AS dept FROM teachers t LEFT JOIN departments d ON t.dept_id = d.id;
小测
左连接中,右表无匹配的行会怎样?
A 填 NULL
B 报错
C 跳过该行
D 填 0
第 16 课 / 共 21 课

多表连接

连接三张及以上表

多个 JOIN 串联,可连接多张表。查询成绩单(学生名 + 课程名 + 分数):

SQL
SELECT s.name AS student, c.name AS course, e.score FROM enrollments e INNER JOIN students s ON e.student_id = s.id INNER JOIN courses c ON e.course_id = c.id ORDER BY e.score DESC LIMIT 5;
小测
连接 3 张表至少需要几个 JOIN?
A 1
B 2
C 3
D 4
第 17 课 / 共 21 课

子查询基础

查询嵌套查询

子查询是嵌套在另一个查询中的查询,常用于 WHERE 条件中。

SQL
SELECT name FROM students WHERE age > (SELECT AVG(age) FROM students);

查询年龄高于平均年龄的学生。

小测
子查询通常可以放在哪里?
A WHERE 或 SELECT 子句中
B 只能放在 FROM
C 只能放在 LIMIT
D 不能嵌套
第 18 课 / 共 21 课

IN 与 NOT IN

集合匹配

IN 匹配列表中的任意值,NOT IN 匹配不在列表中的值。

SQL
SELECT name FROM students WHERE dept_id IN (1, 2);

子查询返回的列表也可用于 IN:

SQL
SELECT name FROM teachers WHERE dept_id IN (SELECT id FROM departments WHERE building = '理学楼');
小测
查询 id 为 1 或 2 的院系学生,正确写法?
A WHERE dept_id IN (1, 2)
B WHERE dept_id = 1 OR 2
C WHERE dept_id IN 1, 2
D WHERE dept_id = (1, 2)
第 19 课 / 共 21 课

NULL 值处理

IS NULL 与 IS NOT NULL

NULL 表示缺失数据,不能用 = NULL 判断,必须用 IS NULL

SQL
SELECT * FROM students WHERE age IS NOT NULL;

COALESCE 返回第一个非 NULL 的值:

SQL
SELECT name, COALESCE(age, 0) AS age FROM students LIMIT 3;
小测
判断 age 为 NULL 的正确写法?
A WHERE age IS NULL
B WHERE age = NULL
C WHERE age == NULL
D WHERE age EQUALS NULL
第 20 课 / 共 21 课

常用函数

字符串、数值函数

UPPER/LOWER 大小写转换,LENGTH 求长度,CONCAT 拼接字符串。

SQL
SELECT name, UPPER(name) AS upper_name, LENGTH(name) AS len FROM students LIMIT 3;

ROUND 四舍五入,ABS 绝对值。

SQL
SELECT AVG(score) AS avg_score, ROUND(AVG(score), 2) AS rounded FROM enrollments;
小测
将字符串转为大写用哪个函数?
A UPPER()
B BIG()
C CAPITAL()
D TO_UPPER()
第 21 课 / 共 21 课

综合实战

综合运用所学知识

查询每门课程的平均分,并按平均分降序排列:

SQL
SELECT c.name AS course, ROUND(AVG(e.score), 1) AS avg_score FROM enrollments e INNER JOIN courses c ON e.course_id = c.id GROUP BY c.name ORDER BY avg_score DESC;

查询平均分最高的学生:

SQL
SELECT s.name, AVG(e.score) AS avg_score FROM enrollments e INNER JOIN students s ON e.student_id = s.id GROUP BY s.name ORDER BY avg_score DESC LIMIT 1;
🎉
恭喜完成 21 课!你已掌握 MySQL 基础,可以继续深入学习索引、事务、视图等进阶主题。
小测
多表统计排序应组合使用?
A JOIN + GROUP BY + ORDER BY
B INSERT + UPDATE
C CREATE + DROP
D LIMIT + OFFSET