认识 SQL
数据库是按结构组织的数据集合,MySQL 是最流行的关系型数据库之一。
SQL(Structured Query Language)是操作数据库的标准语言,本教程涵盖查询、插入、更新、删除等核心操作。
先看看数据库里有哪些表:
SHOW TABLES; 查看 students 表的结构:
DESC students; SELECT 基础
SELECT 用于从表中查询数据,* 表示所有列。
SELECT * FROM students; 也可以指定列名,用逗号分隔:
SELECT name, age, gender FROM students; WHERE 条件过滤
WHERE 子句用于筛选满足条件的行。
SELECT * FROM students WHERE age > 20; 支持的比较运算符:= > < >= <= <> !=。
SELECT * FROM students WHERE gender = '女'; 用 AND / OR 组合多个条件:
SELECT * FROM students WHERE age >= 20 AND gender = '男'; ORDER BY 排序
ORDER BY 按列排序,ASC 升序(默认),DESC 降序。
SELECT * FROM students ORDER BY age DESC; 可按多列排序,优先级从左到右:
SELECT * FROM students ORDER BY dept_id ASC, age DESC; LIMIT 分页
LIMIT 限制返回的行数,常用于分页。
SELECT * FROM students LIMIT 3; LIMIT 偏移量, 数量 实现分页查询:
SELECT * FROM students LIMIT 2, 3; 聚合函数
聚合函数对一组值计算,返回单个值。
SELECT COUNT(*) FROM students; SELECT AVG(age) FROM students; SELECT MAX(score), MIN(score) FROM enrollments; GROUP BY 分组
GROUP BY 按列分组,常与聚合函数配合使用。
SELECT dept_id, COUNT(*) FROM students GROUP BY dept_id; SELECT gender, AVG(age) FROM students GROUP BY gender; HAVING 分组过滤
HAVING 用于过滤分组后的结果,相当于分组后的 WHERE。
SELECT dept_id, COUNT(*) AS cnt FROM students GROUP BY dept_id HAVING cnt > 2; DISTINCT 去重
DISTINCT 去除查询结果中的重复行。
SELECT DISTINCT gender FROM students; SELECT DISTINCT dept_id, gender FROM students; INSERT 插入数据
INSERT INTO 向表中插入数据。
INSERT INTO students (name, gender, age, dept_id, enroll_year) VALUES ('测试同学', '男', 20, 1, 2024); 插入后查询验证:
SELECT * FROM students ORDER BY id DESC LIMIT 1; UPDATE 更新数据
UPDATE 修改满足条件的行。
UPDATE students SET age = 21 WHERE name = '赵小明'; DELETE 删除数据
DELETE 删除满足条件的行。
DELETE FROM students WHERE name = '测试同学'; 建表与删表
CREATE TABLE 创建新表,需定义列名和类型。
CREATE TABLE clubs (id INT, name VARCHAR, leader VARCHAR); 查看刚创建的表:
DESC clubs; DROP TABLE 删除整张表(结构连同数据):
DROP TABLE clubs; INNER JOIN 内连接
INNER JOIN 根据关联条件合并两表,只返回两表都匹配的行。
SELECT students.name, departments.name AS dept FROM students INNER JOIN departments ON students.dept_id = departments.id; 使用表别名简化书写:
SELECT s.name, d.name AS dept FROM students s INNER JOIN departments d ON s.dept_id = d.id LIMIT 5; LEFT JOIN 左连接
LEFT JOIN 保留左表所有行,右表无匹配时填充 NULL。
SELECT t.name, d.name AS dept FROM teachers t LEFT JOIN departments d ON t.dept_id = d.id; 多表连接
多个 JOIN 串联,可连接多张表。查询成绩单(学生名 + 课程名 + 分数):
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; 子查询基础
子查询是嵌套在另一个查询中的查询,常用于 WHERE 条件中。
SELECT name FROM students WHERE age > (SELECT AVG(age) FROM students); 查询年龄高于平均年龄的学生。
IN 与 NOT IN
IN 匹配列表中的任意值,NOT IN 匹配不在列表中的值。
SELECT name FROM students WHERE dept_id IN (1, 2); 子查询返回的列表也可用于 IN:
SELECT name FROM teachers WHERE dept_id IN (SELECT id FROM departments WHERE building = '理学楼'); NULL 值处理
NULL 表示缺失数据,不能用 = NULL 判断,必须用 IS NULL。
SELECT * FROM students WHERE age IS NOT NULL; COALESCE 返回第一个非 NULL 的值:
SELECT name, COALESCE(age, 0) AS age FROM students LIMIT 3; 常用函数
UPPER/LOWER 大小写转换,LENGTH 求长度,CONCAT 拼接字符串。
SELECT name, UPPER(name) AS upper_name, LENGTH(name) AS len FROM students LIMIT 3; ROUND 四舍五入,ABS 绝对值。
SELECT AVG(score) AS avg_score, ROUND(AVG(score), 2) AS rounded FROM enrollments; 综合实战
查询每门课程的平均分,并按平均分降序排列:
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; 查询平均分最高的学生:
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;