100条SQL语句分类精讲:从基础到进阶的实操指南
100条SQL语句分类精讲:从基础到进阶的实操指南
一、基础查询操作(10条)
1. 查询全表数据
SELECT * FROM 表名;
(提示:生产环境慎用*
,明确列名可减少IO消耗,提升效率。)
2. 查询指定列
SELECT 列1, 列2, 列3 FROM 表名;
3. 去重查询(DISTINCT)
SELECT DISTINCT 列名 FROM 表名;
(过滤列值重复的行,多列去重需用DISTINCT 列1, 列2
。)
4. 限制结果行数(LIMIT)
SELECT * FROM 表名 LIMIT 10; -- MySQL/PgSQL语法
-- SQL Server: SELECT TOP 10 * FROM 表名;
-- Oracle: SELECT * FROM 表名 WHERE ROWNUM <= 10;
5. 分页查询(LIMIT + OFFSET)
SELECT * FROM 表名 LIMIT 20 OFFSET 10; -- 跳过前10条,取20条
6. 列别名(AS)
SELECT 列名 AS 别名 FROM 表名;
SELECT 列1 + 列2 AS 计算列 FROM 表名; -- 支持表达式
7. 表别名(简化多表查询)
SELECT u.列1, o.列2
FROM 用户表 u
JOIN 订单表 o ON u.id = o.user_id;
8. 空值替换(COALESCE)
SELECT COALESCE(列名, '默认值') FROM 表名; -- 列值为NULL时返回默认值
9. 行拼接(CONCAT)
SELECT CONCAT(姓, '·', 名) AS 全名 FROM 表名;
10. 大小写转换(UPPER/LOWER)
SELECT UPPER(列名) AS 大写值 FROM 表名;
SELECT LOWER(列名) AS 小写值 FROM 表名;
二、条件筛选与排序(15条)
11. 等于条件(=)
SELECT * FROM 表名 WHERE 列名 = '目标值';
12. 不等于条件(!= / <>)
SELECT * FROM 表名 WHERE 列名 != '排除值';
13. 范围查询(BETWEEN)
SELECT * FROM 表名 WHERE 列名 BETWEEN 10 AND 20; -- 闭区间 [10,20]
14. 多值匹配(IN)
SELECT * FROM 表名 WHERE 列名 IN ('值1', '值2', '值3');
15. 反选多值(NOT IN)
SELECT * FROM 表名 WHERE 列名 NOT IN ('值1', '值2');
16. 模糊查询(LIKE)
SELECT * FROM 表名 WHERE 列名 LIKE '%关键字%'; -- 包含关键字
SELECT * FROM 表名 WHERE 列名 LIKE '前缀%'; -- 以前缀开头
SELECT * FROM 表名 WHERE 列名 LIKE '_字符_'; -- 单字符匹配(如“张_”匹配“张三”)
17. 空值判断(IS NULL / IS NOT NULL)
SELECT * FROM 表名 WHERE 列名 IS NULL;
SELECT * FROM 表名 WHERE 列名 IS NOT NULL;
18. 逻辑运算(AND / OR / NOT)
SELECT * FROM 表名
WHERE 条件1 AND (条件2 OR 条件3); -- 注意括号优先级
19. 单字段排序(ORDER BY)
SELECT * FROM 表名 ORDER BY 列名 DESC; -- DESC降序,默认ASC升序
20. 多字段排序
SELECT * FROM 表名
ORDER BY 列1 ASC, 列2 DESC; -- 先按列1升序,再按列2降序
21. 随机排序(ORDER BY RAND())
SELECT * FROM 表名 ORDER BY RAND() LIMIT 5; -- 随机取5条(MySQL语法)
22. 条件排序(CASE WHEN + ORDER BY)
SELECT * FROM 表名
ORDER BY CASE WHEN 列名 = '特殊值' THEN 0 ELSE 1 END, 列名;
23. 空值排序优先级(NULLS FIRST / LAST)
-- PostgreSQL/Oracle语法,控制NULL值排序位置
SELECT * FROM 表名 ORDER BY 列名 NULLS LAST;
三、聚合与分组统计(12条)
24. 计数(COUNT)
SELECT COUNT(*) AS 总行数 FROM 表名; -- 含NULL
SELECT COUNT(列名) AS 非空行数 FROM 表名; -- 忽略NULL
SELECT COUNT(DISTINCT 列名) AS 去重计数 FROM 表名;
25. 求和(SUM)
SELECT SUM(列名) AS 总和 FROM 表名 WHERE 条件;
26. 平均值(AVG)
SELECT AVG(列名) AS 平均值 FROM 表名;
27. 最大值(MAX)与最小值(MIN)
SELECT MAX(列名) AS 最大值, MIN(列名) AS 最小值 FROM 表名;
28. 分组统计(GROUP BY)
SELECT 分组列, COUNT(*) AS 数量
FROM 表名
GROUP BY 分组列;
29. 多列分组
SELECT 列1, 列2, COUNT(*) AS 数量
FROM 表名
GROUP BY 列1, 列2; -- 需与SELECT列一一对应(除聚合函数)
30. 分组筛选(HAVING)
SELECT 分组列, COUNT(*) AS 数量
FROM 表名
GROUP BY 分组列
HAVING 数量 > 10; -- 过滤分组结果(区别于WHERE,HAVING用聚合结果)
31. 分组内排序(WITH ROLLUP)
SELECT 分组列, COUNT(*) AS 数量
FROM 表名
GROUP BY 分组列 WITH ROLLUP; -- 自动生成小计和总计
32. 窗口函数 + 聚合(OVER)
SELECT 列名, SUM(列名) OVER (PARTITION BY 分组列) AS 组内总和
FROM 表名;
33. 百分比计算(SUM + OVER)
SELECT 列名, SUM(列名) OVER () AS 总计, (列名 / SUM(列名) OVER ()) * 100 AS 占比
FROM 表名;
34. 移动聚合(ROWS BETWEEN)
SELECT 日期, 销售额, AVG(销售额) OVER (ORDER BY 日期 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS 近3日平均
FROM 表名;
四、多表连接查询(15条)
35. 内连接(INNER JOIN)
SELECT a.列1, b.列2
FROM 表A a
INNER JOIN 表B b ON a.关联列 = b.关联列; -- 仅返回匹配行
36. 左连接(LEFT JOIN)
SELECT a.列1, b.列2
FROM 表A a
LEFT JOIN 表B b ON a.关联列 = b.关联列; -- 保留表A所有行,表B无匹配则为NULL
37. 右连接(RIGHT JOIN)
SELECT a.列1, b.列2
FROM 表A a
RIGHT JOIN 表B b ON a.关联列 = b.关联列; -- 保留表B所有行
38. 全连接(FULL JOIN)
-- MySQL不支持,需用UNION模拟
SELECT a.列1, b.列2
FROM 表A a
LEFT JOIN 表B b ON a.关联列 = b.关联列
UNION
SELECT a.列1, b.列2
FROM 表A a
RIGHT JOIN 表B b ON a.关联列 = b.关联列;
39. 自连接(同表关联)
SELECT e.姓名 AS 员工, l.姓名 AS 领导
FROM 员工表 e
LEFT JOIN 员工表 l ON e.领导ID = l.员工ID; -- 自身关联查层级
40. 交叉连接(CROSS JOIN)
SELECT * FROM 表A
CROSS JOIN 表B; -- 笛卡尔积,慎用(数据量=表A行数×表B行数)
41. 连接 + 条件筛选
SELECT a.列1, b.列2
FROM 表A a
JOIN 表B b ON a.关联列 = b.关联列
WHERE a.列3 = '条件'; -- 连接后过滤
42. 连接 + 分组聚合
SELECT a.分组列, COUNT(b.列名) AS 数量
FROM 表A a
LEFT JOIN 表B b ON a.关联列 = b.关联列
GROUP BY a.分组列;
43. 多表连接(三表关联)
SELECT u.姓名, o.订单号, p.商品名
FROM 用户表 u
JOIN 订单表 o ON u.id = o.user_id
JOIN 订单详情表 od ON o.id = od.order_id
JOIN 商品表 p ON od.product_id = p.id;
44. 连接 + 子查询
SELECT a.列1, b.列2
FROM (SELECT * FROM 表A WHERE 条件) a
JOIN 表B b ON a.关联列 = b.关联列;
45. 强制索引(优化连接性能)
-- MySQL语法,指定索引加速连接
SELECT * FROM 表A FORCE INDEX(索引名)
JOIN 表B ON a.列 = b.列;
五、子查询深度应用(12条)
46. WHERE 子查询(单行结果)
SELECT * FROM 表名
WHERE 列名 > (SELECT AVG(列名) FROM 表名); -- 对比子查询结果
47. WHERE 子查询(多行结果,IN)
SELECT * FROM 表名
WHERE 列名 IN (SELECT 列名 FROM 子表 WHERE 条件);
48. WHERE 子查询(多行结果,ANY/ALL)
SELECT * FROM 表名
WHERE 列名 > ANY (SELECT 列名 FROM 子表); -- 大于子查询任意值
SELECT * FROM 表名
WHERE 列名 > ALL (SELECT 列名 FROM 子表); -- 大于子查询所有值
49. 存在性判断(EXISTS)
SELECT * FROM 表A a
WHERE EXISTS (SELECT 1 FROM 表B b WHERE a.关联列 = b.关联列);
50. 反存在性判断(NOT EXISTS)
SELECT * FROM 表A a
WHERE NOT EXISTS (SELECT 1 FROM 表B b WHERE a.关联列 = b.关联列);
51. 派生表(FROM 子查询)
SELECT 列1, AVG(列2)
FROM ( SELECT 列1, 列2 FROM 表名 WHERE 条件
) AS 子表
GROUP BY 列1;
52. SELECT 子查询(关联子查询)
SELECT 列1, (SELECT COUNT(*) FROM 子表 WHERE 子表.关联列 = 主表.列1) AS 计数
FROM 主表;
53. 插入子查询(INSERT … SELECT)
INSERT INTO 目标表 (列1, 列2)
SELECT 列1, 列2 FROM 源表 WHERE 条件;
54. 更新子查询(UPDATE + 子查询)
UPDATE 表名 a
SET 列1 = (SELECT 列2 FROM 子表 b WHERE a.关联列 = b.关联列)
WHERE EXISTS (SELECT 1 FROM 子表 b WHERE a.关联列 = b.关联列);
55. 删除子查询(DELETE + 子查询)
DELETE FROM 表名
WHERE 关联列 IN (SELECT 关联列 FROM 子表 WHERE 条件);
六、数据操纵(增删改,10条)
56. 插入单行数据
INSERT INTO 表名 (列1, 列2) VALUES ('值1', '值2'); -- 需匹配列顺序
57. 插入多行数据
INSERT INTO 表名 (列1, 列2)
VALUES ('值1', '值2'), ('值3', '值4'), ('值5', '值6');
58. 全列插入(省略列名)
INSERT INTO 表名 VALUES (NULL, '值1', '值2'); -- 需按表结构顺序,自增列传NULL
59. 更新单行数据
UPDATE 表名
SET 列1 = '新值'
WHERE 主键列 = 123; -- 务必加WHERE,否则全表更新!
60. 更新多列数据
UPDATE 表名
SET 列1 = '新值1', 列2 = '新值2'
WHERE 条件;
61. 更新关联表数据(多表更新)
-- MySQL语法
UPDATE 表A a
JOIN 表B b ON a.关联列 = b.关联列
SET a.列1 = b.列2
WHERE 条件;
62. 删除指定数据
DELETE FROM 表名 WHERE 条件; -- 务必加WHERE,否则全表删除!
63. 删除关联数据(多表删除)
-- MySQL语法
DELETE a FROM 表A a
JOIN 表B b ON a.关联列 = b.关联列
WHERE b.条件;
64. 快速清空表(TRUNCATE)
TRUNCATE TABLE 表名; -- 不可回滚,自增ID重置(DDL操作)
65. 替换数据(REPLACE INTO)
REPLACE INTO 表名 (列1, 列2) VALUES ('值1', '值2'); -- 存在则更新,否则插入
七、数据定义(表结构,10条)
66. 创建表(含约束)
CREATE TABLE 表名 ( ID INT PRIMARY KEY AUTO_INCREMENT, -- MySQL自增 名称 VARCHAR(50) NOT NULL, -- 非空约束 邮箱 VARCHAR(100) UNIQUE, -- 唯一约束 状态 TINYINT DEFAULT 1, -- 默认值 外键列 INT, FOREIGN KEY (外键列) REFERENCES 主表(主键列) -- 外键约束
);
67. 添加列(ALTER TABLE)
ALTER TABLE 表名 ADD 新列 VARCHAR(50) AFTER 已有列; -- 在指定列后添加
68. 修改列属性(ALTER TABLE)
ALTER TABLE 表名 MODIFY 列名 VARCHAR(100) NOT NULL; -- 修改类型/约束
69. 重命名列(ALTER TABLE)
-- MySQL语法
ALTER TABLE 表名 CHANGE 旧列名 新列名 VARCHAR(50);
70. 删除列(ALTER TABLE)
ALTER TABLE 表名 DROP COLUMN 列名;
71. 添加外键约束
ALTER TABLE 子表
ADD CONSTRAINT 外键名
FOREIGN KEY (外键列) REFERENCES 主表(主键列)
ON DELETE CASCADE; -- 级联删除
72. 删除外键约束
-- 先查外键名:SHOW CREATE TABLE 表名;
ALTER TABLE 表名 DROP FOREIGN KEY 外键名;
73. 创建索引(加速查询)
CREATE INDEX 索引名 ON 表名(列名); -- 单字段索引
CREATE UNIQUE INDEX 唯一索引名 ON 表名(列名); -- 唯一索引
CREATE INDEX 复合索引 ON 表名(列1, 列2); -- 复合索引(遵循最左匹配)
74. 删除索引
DROP INDEX 索引名 ON 表名; -- MySQL语法
75. 重命名表
ALTER TABLE 旧表名 RENAME TO 新表名;
八、高级函数与窗口函数(15条)
76. 日期函数(NOW/CURDATE)
SELECT NOW() AS 当前时间; -- 日期+时间
SELECT CURDATE() AS 当前日期;
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY) AS 七天后; -- 日期加减
77. 日期格式化(DATE_FORMAT)
SELECT DATE_FORMAT(时间列, '%Y-%m-%d %H:%i:%s') AS 格式化时间 FROM 表名;
78. 条件判断(CASE WHEN)
SELECT 分数,
CASE WHEN 分数 >= 90 THEN '优秀' WHEN 分数 >= 60 THEN '合格' ELSE '不合格'
END AS 等级
FROM 表名;
79. 空值处理(IFNULL/COALESCE)
SELECT IFNULL(列名, '默认值') AS 处理后 FROM 表名; -- MySQL
SELECT COALESCE(列名, '默认值', '备选值') FROM 表名; -- 多值 fallback
80. 数学函数(ROUND/FLOOR)
SELECT ROUND(数值列, 1) AS 四舍五入 FROM 表名; -- 保留1位小数
SELECT FLOOR(数值列) AS 向下取整 FROM 表名;
81. 窗口函数 - 行号(ROW_NUMBER)
SELECT 姓名, 分数,
ROW_NUMBER() OVER (ORDER BY 分数 DESC) AS 排名
FROM 表名; -- 每行唯一排名
82. 窗口函数 - 排名(RANK/DENSE_RANK)
SELECT 姓名, 分数,
RANK() OVER (ORDER BY 分数 DESC) AS 排名, -- 相同分数同排名,下一名跳空
DENSE_RANK() OVER (ORDER BY 分数 DESC) AS 密集排名 -- 相同分数同排名,下一名不跳空
FROM 表名;
83. 窗口函数 - 分组排名
SELECT 类别, 商品名, 销售额,
ROW_NUMBER() OVER (PARTITION BY 类别 ORDER BY 销售额 DESC) AS 类内排名
FROM 表名;
84. 窗口函数 - 累计求和
SELECT 日期, 销售额,
SUM(销售额) OVER (ORDER BY 日期) AS 累计销售额
FROM 表名;
85. 窗口函数 - 移动平均
SELECT 日期, 销售额,
AVG(销售额) OVER (ORDER BY 日期 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS 近3日平均
FROM 表名;
86. 窗口函数 - 首尾值(FIRST_VALUE/LAST_VALUE)
SELECT 姓名, 分数,
FIRST_VALUE(姓名) OVER (ORDER BY 分数 DESC) AS 最高分姓名,
LAST_VALUE(姓名) OVER (ORDER BY 分数 DESC) AS 最低分姓名
FROM 表名;
87. 窗口函数 - 前后值(LAG/LEAD)
SELECT 日期, 销售额,
LAG(销售额, 1) OVER (ORDER BY 日期) AS 前一日销售额,
LEAD(销售额, 1) OVER (ORDER BY 日期) AS 后一日销售额
FROM 表名;
88. JSON 函数(MySQL 8+)
SELECT JSON_EXTRACT(字段, '$.key') AS 提取值 FROM 表名; -- 解析JSON
SELECT JSON_OBJECT('name', 列名, 'age', 列名) AS JSON列 FROM 表名; -- 生成JSON
89. 正则表达式(REGEXP)
SELECT * FROM 表名 WHERE 列名 REGEXP '^[0-9]{3}-[0-9]{8}$'; -- 匹配手机号格式
九、事务与控制(8条)
90. 开启事务
START TRANSACTION; -- 或 BEGIN;
91. 提交事务
COMMIT; -- 确认修改,永久生效
92. 回滚事务
ROLLBACK; -- 撤销所有修改,回退到事务开始状态
93. 保存点(局部回滚)
SAVEPOINT 保存点名称; -- 创建保存点
ROLLBACK TO 保存点名称; -- 回滚到保存点,后续操作可提交
94. 事务隔离级别(查看/设置)
SELECT @@transaction_isolation; -- 查看隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; -- 设置会话级别
95. 锁机制(FOR UPDATE)
SELECT * FROM 表名 WHERE 条件 FOR UPDATE; -- 行级锁,防止并发修改
96. 只读事务
START TRANSACTION READ ONLY; -- 声明只读事务(部分数据库支持)
97. 事务嵌套(Savepoint 进阶)
START TRANSACTION;
SAVEPOINT sp1;
-- 操作1
SAVEPOINT sp2;
-- 操作2
ROLLBACK TO sp1; -- 回退操作2,保留操作1
COMMIT;
收藏本文,遇到问题时直接检索分类,让SQL从“语法记忆”变成“业务工具”! 🚀