下面按「增删改查 → 条件与排序 → 聚合 → 关联 → 分组 → 事务 → 索引」的顺序说明,不依赖你项目里的任何文件。
一、增删改查(CRUD)
1. 查 --- SELECT(Read)
SELECT 列1, 列2 FROM 表名;
SELECT * FROM users; -- 查所有列
SELECT name, email FROM users; -- 查指定列
2. 增 --- INSERT(Create)
INSERT INTO users (name, email, age)
VALUES ('张三', 'zhangsan@example.com', 25);
-- 一次插入多行
INSERT INTO users (name, email) VALUES
('李四', 'lisi@example.com'),
('王五', 'wangwu@example.com');
3. 改 --- UPDATE(Update)
UPDATE users
SET age = 26, email = 'new@example.com'
WHERE id = 1; -- 几乎总是要带 WHERE,否则整表都会被改
4. 删 --- DELETE(Delete)
DELETE FROM users WHERE id = 1; -- 删指定行
DELETE FROM users; -- 删全表(慎用)
二、条件筛选:WHERE、AND、BETWEEN
WHERE --- 过滤行
SELECT * FROM users WHERE age > 18;
SELECT * FROM users WHERE city = '北京';
SELECT * FROM users WHERE email IS NULL;
SELECT * FROM users WHERE name LIKE '张%'; -- 模糊匹配
AND / OR --- 组合条件
SELECT * FROM users
WHERE age >= 18 AND city = '上海';
SELECT * FROM users
WHERE status = 'active' OR status = 'pending';
BETWEEN --- 范围(含边界)
SELECT * FROM orders
WHERE amount BETWEEN 100 AND 500;
-- 等价于:amount >= 100 AND amount <= 500
SELECT * FROM users
WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31';
IN / NOT IN --- 枚举多个值
SELECT * FROM users WHERE city IN ('北京', '上海', '广州');
三、排序与分页:ORDER BY、ASC、DESC、LIMIT
ORDER BY --- 排序
SELECT * FROM users ORDER BY age ASC; -- 升序(默认)
SELECT * FROM users ORDER BY age DESC; -- 降序
-- 多列排序:先按 city,再按 age 降序
SELECT * FROM users
ORDER BY city ASC, age DESC;
| 关键字 | 含义 |
|---|---|
ASC |
升序(小→大,A→Z) |
DESC |
降序(大→小,Z→A) |
LIMIT --- 限制返回行数(分页常用)
-- MySQL / PostgreSQL 常见写法
SELECT * FROM users ORDER BY id LIMIT 10; -- 前 10 条
SELECT * FROM users ORDER BY id LIMIT 10 OFFSET 20; -- 跳过 20 条,取 10 条(第 3 页)
-- SQL Server 用 TOP 或 OFFSET/FETCH
-- Oracle 用 FETCH FIRST n ROWS ONLY
四、聚合函数:SUM、AVG、MAX、MIN
对一列或多列做统计,通常配合 GROUP BY 或单独用在整表/筛选结果上。
-- 全表统计
SELECT
COUNT(*) AS total_users,
AVG(age) AS avg_age,
MAX(age) AS max_age,
MIN(age) AS min_age,
SUM(salary) AS total_salary
FROM users;
-- 带条件
SELECT AVG(amount) FROM orders WHERE status = 'completed';
| 函数 | 作用 |
|---|---|
COUNT(*) |
行数 |
SUM(col) |
求和 |
AVG(col) |
平均值 |
MAX(col) |
最大值 |
MIN(col) |
最小值 |
注意:
AVG会忽略NULL;COUNT(*)计所有行,COUNT(col)只计该列非 NULL 的行。
五、表关联:JOIN
当数据分布在多张表时,用 JOIN 按关联键把行拼在一起。
假设:
-
users(id, name) -
orders(id, user_id, amount)
INNER JOIN --- 只保留两边都能匹配上的行
SELECT u.name, o.amount
FROM users u
INNER JOIN orders o ON u.id = o.user_id;
LEFT JOIN --- 左表全保留,右表无匹配则为 NULL
SELECT u.name, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
-- 即使用户没有订单也会出现在结果里
RIGHT JOIN --- 右表全保留
SELECT u.name, o.amount
FROM users u
RIGHT JOIN orders o ON u.id = o.user_id;
多表关联
SELECT u.name, p.product_name, o.amount
FROM orders o
JOIN users u ON o.user_id = u.id
JOIN products p ON o.product_id = p.id;
要点: ON 后面写关联条件(通常是外键 = 主键);WHERE 写业务过滤条件。
六、GROUP BY --- 分组聚合
按某一列(或多列)分组,再对每组做 SUM / AVG / COUNT 等。
示例数据
假设 users 表当前数据如下:
| id | name | city | age |
|---|---|---|---|
| 1 | 张三 | 北京 | 25 |
| 2 | 李四 | 北京 | 30 |
| 3 | 王五 | 北京 | 28 |
| 4 | 赵六 | 上海 | 22 |
| 5 | 孙七 | 上海 | 35 |
| 6 | 周八 | 广州 | 40 |
| 7 | 吴九 | 北京 | 26 |
| 8 | 郑十 | 北京 | 32 |
| 9 | 钱一 | 北京 | 24 |
| 10 | 陈二 | 北京 | 29 |
| 11 | 刘三 | 北京 | 27 |
| 12 | 黄四 | 北京 | 31 |
| 13 | 林五 | 北京 | 23 |
| 14 | 何六 | 北京 | 33 |
北京 11 人、上海 2 人、广州 1 人,便于演示
HAVING过滤。
示例 1:按城市统计人数与平均年龄
-- 每个城市的用户数量和平均年龄
SELECT
city,
COUNT(*) AS user_count,
AVG(age) AS avg_age
FROM users
GROUP BY city;
执行顺序(逻辑步骤,不是写 SQL 的顺序):
| 步骤 | 子句 | 本例做了什么 |
|---|---|---|
| 1 | FROM |
读取 users 全部 14 行 |
| 2 | WHERE |
无,跳过 |
| 3 | GROUP BY |
按 city 分成 3 组:北京 11 行、上海 2 行、广州 1 行 |
| 4 | HAVING |
无,跳过 |
| 5 | SELECT |
每组计算 COUNT(*)、AVG(age),输出 city |
| 6 | ORDER BY |
无,跳过 |
| 7 | LIMIT |
无,跳过 |
分组过程示意:
北京组 → 11 行 → COUNT(*)=11, AVG(age)=(25+30+28+26+32+24+29+27+31+23+33)/11 = 28.00
上海组 → 2 行 → COUNT(*)=2, AVG(age)=(22+35)/2 = 28.50
广州组 → 1 行 → COUNT(*)=1, AVG(age)=40.00
查询结果:
| city | user_count | avg_age |
|---|---|---|
| 北京 | 11 | 27.36 |
| 上海 | 2 | 28.50 |
| 广州 | 1 | 40.00 |
示例 2:HAVING 过滤分组结果
-- 配合 HAVING 过滤分组结果(类似 WHERE,但针对聚合后的组)
SELECT city, COUNT(*) AS cnt
FROM users
GROUP BY city
HAVING COUNT(*) > 10;
HAVING 过滤示意:
北京组 → COUNT(*)=11 → 11 > 10 ✓ 保留
上海组 → COUNT(*)=2 → 2 > 10 ✗ 丢弃
广州组 → COUNT(*)=1 → 1 > 10 ✗ 丢弃
查询结果:
| city | cnt |
|---|---|
| 北京 | 11 |
记忆口诀: 先
FROM拿表 →WHERE筛行 →GROUP BY分组 →HAVING筛组 →SELECT选列 →ORDER BY排序 →LIMIT截断。
WHERE vs HAVING
| 关键字 | 作用 |
|---|---|
WHERE |
分组之前过滤行 |
HAVING |
分组之后过滤组 |