整理了一份 SQL 基础语法速记清单,涵盖日常工作中 90% 以上的场景。建议收藏以备查阅。
一、核心分类(记住这个框架)
| 分类 | 英文缩写 | 核心动词 |
|---|
| 数据查询 | DQL | SELECT |
| 数据操作 | DML | INSERT, UPDATE, DELETE |
| 数据定义 | DDL | CREATE, ALTER, DROP |
| 数据控制 | DCL | GRANT, REVOKE |
二、查询语法(SELECT)—— 最常用
1. 基础查询顺序(物理书写顺序)
SELECT [DISTINCT] 列名1, 列名2, 聚合函数
FROM 表名
JOIN 其他表 ON 连接条件
WHERE 行级过滤条件
GROUP BY 分组列
HAVING 组级过滤条件(与聚合函数配合)
ORDER BY 排序列 [ASC|DESC]
LIMIT [偏移量,] 行数;
2. 执行逻辑顺序(重要!帮你理解报错)
FROM → JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT
口诀:先取表,再关联,行过滤,再分组,组过滤,选列,去重,排序,截取。
三、常用过滤条件(WHERE)
| 场景 | 写法 |
|---|
| 等值 | WHERE age = 25 |
| 不等值 | WHERE age <> 25 或 != |
| 范围 | WHERE age BETWEEN 18 AND 30 |
| 列表 | WHERE city IN ('北京','上海') |
| 模糊 | WHERE name LIKE '张%' (%任意多,_单个) |
| 空值 | WHERE email IS NULL (千万不能用 = NULL) |
| 组合 | AND / OR / NOT |
| 转义 | WHERE path LIKE '%\_2026%' ESCAPE '\' |
四、常用聚合函数(配合 GROUP BY)
| 函数 | 作用 |
|---|
COUNT(*) | 计数(含空行) |
COUNT(列) | 计数(忽略 NULL) |
SUM(列) | 求和 |
AVG(列) | 平均(忽略 NULL) |
MAX(列) | 最大值 |
MIN(列) | 最小值 |
GROUP_CONCAT(列) | 字符串拼接(MySQL) |
注意:SELECT 中非聚合列,必须出现在 GROUP BY 中(严格模式)。
五、多表连接(JOIN)
SELECT * FROM A INNER JOIN B ON A.id = B.a_id;
SELECT * FROM A LEFT JOIN B ON A.id = B.a_id;
SELECT * FROM A RIGHT JOIN B ON A.id = B.a_id;
SELECT * FROM A LEFT JOIN B UNION
SELECT * FROM A RIGHT JOIN B;
SELECT a.name, b.name FROM emp a JOIN emp b ON a.manager_id = b.id;
六、数据修改(DML)
插入
INSERT INTO 表名 VALUES (值1, 值2, ...);
INSERT INTO 表名 (列1, 列2) VALUES (值1, 值2);
INSERT INTO 表名 VALUES (1,'a'), (2,'b'), (3,'c');
更新(务必加 WHERE)
UPDATE 表名 SET 列1 = 新值1, 列2 = 新值2 WHERE 条件;
删除(务必加 WHERE)
DELETE FROM 表名 WHERE 条件;
TRUNCATE TABLE 表名;
七、表结构操作(DDL)—— 简洁版
CREATE TABLE 表名 (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
ALTER TABLE 表名 ADD 列名 数据类型;
ALTER TABLE 表名 MODIFY 列名 新数据类型;
ALTER TABLE 表名 ALTER COLUMN 列名 TYPE 新类型;
ALTER TABLE 表名 DROP COLUMN 列名;
DROP TABLE 表名;
八、常用函数速查
字符串
CONCAT('a','b') → 'ab'
SUBSTRING('hello',1,3) → 'hel'
UPPER/LOWER 大小写
TRIM 去空格
LENGTH 字节长度,CHAR_LENGTH 字符长度
日期时间(MySQL)
NOW() 当前时间
CURDATE() 当前日期
YEAR(date) / MONTH(date) / DAY(date)
DATE_ADD(NOW(), INTERVAL 1 DAY)
DATEDIFF(date1, date2) 相差天数
条件判断
SELECT name,
CASE
WHEN score >= 90 THEN '优秀'
WHEN score >= 60 THEN '及格'
ELSE '不及格'
END AS 等级
FROM students;
SELECT IF(score >= 60, '通过', '不通过') FROM students;
九、必须避开的 5 个大坑 ⚠️
| 错误写法 | 正确写法 | 原因 |
|---|
WHERE name = NULL | WHERE name IS NULL | NULL 不能用 = 判断 |
SELECT * FROM a WHERE id IN (SELECT ...) 子查询返回多列 | 只返回一列 | IN 后只能有一列 |
GROUP BY a 但 SELECT b | 把 b 也加到 GROUP BY 或聚合 | 非聚合列必须分组 |
DELETE / UPDATE 不加 WHERE | 先用 SELECT 验证条件 | 容易误删全表 |
HAVING score > 80(score 未聚合) | 用 WHERE 过滤原始行 | HAVING 用于聚合后 |
十、实用小技巧(面试/工作加分)
1. 去重计数
SELECT COUNT(DISTINCT user_id) FROM orders;
2. 分组取每组前 N 条(窗口函数,必学)
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rn
FROM emp
) t WHERE rn <= 3;
3. 用 EXISTS 代替 IN(子查询数据量大时效率高)
SELECT * FROM emp e WHERE EXISTS (
SELECT 1 FROM dept d WHERE e.dept_id = d.id
);
4. 复制表结构(不复制数据)
CREATE TABLE 新表 LIKE 旧表;
CREATE TABLE 新表 AS SELECT * FROM 旧表 WHERE 1=0;
最后送你一个 万能查询模板(可直接套用)
SELECT
分组维度,
COUNT(*) AS 数量,
SUM(金额) AS 总金额
FROM 事实表
WHERE 日期 >= '2026-01-01'
AND 状态 = '已完成'
GROUP BY 分组维度
HAVING COUNT(*) > 10
ORDER BY 总金额 DESC
LIMIT 100;