想高效地处理和分析数据,掌握 SQL 查询是每一位开发者和数据分析师的必备技能。本文整理了 21 个最基础的 SQL 查询用法,从简单的列查询、条件筛选,到排序、去重和格式化,每个例子都配有清晰的语法说明、模拟数据与代码演示。无论你是 SQL 新手,还是想巩固基础,这些实例都能帮助你快速上手,应对日常的数据检索需求。(所有代码块和表格均可左右滚动)
1. 查询列
功能说明:从指定表中选取特定列的数据。
基础语法:SELECT 列名 FROM 表名;
| 模拟数据(tb_顾客表): |
顾客编号 |
顾客姓名 |
所在城市 |
邮编 |
电话 |
传真 |
| 1 |
张三 |
北京 |
100000 |
12345678 |
87654321 |
| 2 |
李四 |
上海 |
200000 |
23456789 |
98765432 |
-- 示例:从tb_顾客表中查询顾客姓名列
SELECT 顾客姓名
FROM tb_顾客表;
2. 查询全部信息
功能说明:返回指定表中的所有列和所有行数据。
基础语法:SELECT * FROM 表名;
模拟数据(tb_顾客表):同上表。
-- 示例:从tb_顾客表中查询所有列的所有信息
SELECT *
FROM tb_顾客表;
模拟结果:返回整个tb_顾客表的数据(全部列和行)。
3. 换标题(列别名)
功能说明:为查询结果的列指定新的显示名称(别名)。
基础语法:SELECT 列名 AS '新列名' FROM 表名; (AS可省略)
模拟数据(tb_顾客表):同上表。
-- 示例:为顾客编号、顾客姓名、所在城市列换标题
SELECT
顾客编号 AS '编号',
顾客姓名 AS '姓名',
所在城市 AS '城市'
FROM tb_顾客表;
| 模拟结果: |
编号 |
姓名 |
城市 |
| 1 |
张三 |
北京 |
| 2 |
李四 |
上海 |
4. 添加列(计算列)
功能说明:通过表达式创建新的计算列。
基础语法:SELECT 列名, 表达式 AS 新列名 FROM 表名;
模拟数据(tb_顾客表):同上表。
-- 示例:新增计算列'傻'(电话+传真)和'锅'(邮编+电话)
SELECT
顾客姓名,
邮编,
电话,
传真,
(电话 + 传真) AS '傻', -- 假设电话和传真为数值类型,实际中可能是字符串,这里按数值运算
(邮编 + 电话) AS '锅' -- 同上,注意数据类型匹配
FROM tb_顾客表;
注意:实际应用中,如果 电话 和 传真 是字符串类型(如VARCHAR),则 + 会连接字符串。这里假设它们是数值类型(如INT)。
| 模拟结果(假设为数值): |
顾客姓名 |
邮编 |
电话 |
传真 |
傻 |
锅 |
| 张三 |
100000 |
12345678 |
87654321 |
99999999 |
10012345678 |
| 李四 |
200000 |
23456789 |
98765432 |
122222221 |
20023456789 |
5. 区间查询(选择数据范围)
功能说明:根据条件筛选特定范围内的数据。
基础语法:
SELECT 列名 FROM 表名 WHERE 条件;
BETWEEN ... AND ... 用于指定范围(闭区间)。
模拟数据:
- tb_顾客表:同上表(邮编列)。
-
| mrbooks表: |
图书ID |
图书名称 |
图书价格 |
| 1 |
书A |
68 |
| 2 |
书B |
75 |
| 3 |
书C |
90 |
-- 示例1:查询邮编大于131000的顾客信息
SELECT 顾客姓名, 邮编, 电话, 传真
FROM tb_顾客表
WHERE 邮编 > 131000;
-- 示例2:查询图书价格在68到88之间的记录
SELECT *
FROM mrbooks
WHERE 图书价格 BETWEEN 68 AND 88;
模拟结果:
- 示例1(邮编>131000):返回李四的记录(邮编200000)。
- 示例2:返回图书ID为1(68)和2(75)的记录(假设88包含在内,但90不包含)。
6. 模糊查询
功能说明:使用模式匹配筛选数据(如以特定字符开头)。
基础语法:SELECT 列名 FROM 表名 WHERE 列名 LIKE 模式;
_:匹配任意单个字符。
%:匹配任意多个字符(包括0个)。
模拟数据(mrbooks表):同上表,假设图书价格是字符串类型(如'68元'),如果是数字列不推荐用LIKE。
-- 示例:查询图书价格以数字开头的记录(假设图书价格是字符串,且至少有一个字符)
SELECT *
FROM mrbooks
WHERE 图书价格 LIKE '_%';
模拟结果:返回所有图书价格非空的记录(因为 _% 匹配至少一个字符)。
说明:在 SQL 中,通常不推荐对数字列使用 LIKE 进行模糊匹配,因为 LIKE 是专门为字符串设计的操作符。下面来详细说明:
数字列用 LIKE 的问题
- 数据类型不匹配:数值列(像
INT、DECIMAL 这类)在数据库里是以二进制形式存储的,并非字符串。直接用 LIKE 去匹配,数据库可能会先把数值隐式转换为字符串,这就容易导致性能下降,还可能引发不可预期的结果。
- 索引失效:要是对数值列创建了索引,使用
LIKE 进行查询时,索引就没办法发挥作用,查询效率会变得很低。
- 逻辑不直观:用字符串匹配的方式(例如
_9)去处理数值,逻辑上不够清晰,而且很容易出错。
适用场景(特殊情况)
在某些特定场景下,数字列用 LIKE 也有一定合理性:
- 日期或编码处理:当数值代表的是日期(如
202305)或者编码(如 1001),需要按字符串规则筛选时,就可以使用 LIKE。
-- 筛选2023年5月的数据(假设日期存为YYYYMM格式的INT)
SELECT * FROM orders WHERE order_date LIKE '202305%';
- 兼容旧系统:如果数据库设计不合理,数值列里存的是字符串形式的数据(例如用
INT 存邮编 100000),这时可以用 LIKE。
- 字符串化的数值:有些数据库会把数值当作字符串来处理(比如SQLite默认不严格区分数据类型),在这种情况下,
LIKE 可能会正常工作。
替代方案
对于数值筛选,推荐使用专门的数值操作符,这样逻辑更清晰,性能也更好:
-
筛选个位是9的数值
-- 取模运算(推荐)
WHERE 图书价格 % 10 = 9
-- 范围查询(更灵活)
WHERE 图书价格 BETWEEN 9 AND 99 AND 图书价格 % 10 = 9
-
字符串转换后匹配
-- 显式转换为字符串(不同数据库函数可能不同)
WHERE CAST(图书价格 AS VARCHAR) LIKE '_9'
-- 更安全的写法(避免隐式转换)
WHERE STR(图书价格, 10) LIKE '_9' -- STR是SQL Server的函数
总结:虽然数字列能用 LIKE,但存在以下风险:
- 性能问题:隐式类型转换会让查询变慢。
- 逻辑歧义:比如
WHERE 价格 LIKE '5_',可能会错误地匹配到字符串 '5.9'。
- 兼容性差:在不同数据库(像 MySQL、Oracle)中的表现可能不一样。
建议:优先使用数值运算(如 >、<、BETWEEN)或者函数(如 MOD())来处理数字列,只有在明确需要按字符串规则匹配时,才考虑用 LIKE(同时要确保类型转换是安全的)。
7. 前五名(TOP N)
功能说明:返回按指定列排序后的前N条记录。
基础语法:SELECT TOP N 列名 FROM 表名 ORDER BY 列名 DESC; (DESC表示降序)
| 模拟数据(tb_BookSell表): |
销售ID |
书号 |
书名 |
作者 |
金额 |
| 1 |
B001 |
书A |
作者A |
100 |
| 2 |
B002 |
书B |
作者B |
200 |
| ... |
... |
... |
... |
... |
| 10 |
B010 |
书J |
作者J |
50 |
-- 示例:按金额降序选取前5条记录
SELECT TOP 5 *
FROM tb_BookSell
ORDER BY 金额 DESC;
模拟结果:返回金额最高的5条记录(假设按金额降序排,取前5)。
8. 后五名(分组聚合后排序)
功能说明:按分组计算聚合值(如合计销售金额),然后取排序后的最后N条。
基础语法:
SELECT 列1, 列2, 聚合函数(列3) AS 别名 FROM 表名 GROUP BY 列1, 列2, ... ORDER BY 聚合列 ASC;
TOP N 可用于限制返回行数。
ORDER BY 数字 表示按结果集中的第几列排序(从1开始)。
模拟数据(tb_BookSell表):同上表。
-- 示例:按作者、书号、书名分组计算合计销售金额,并按合计销售金额升序取后5名(即最低的5个)
SELECT TOP 5
书号, 书名, SUM(金额) AS 合计销售金额
FROM tb_BookSell
GROUP BY 书号, 书名, 作者 -- 注意:为了分组,所有非聚合列都应出现在GROUP BY中
ORDER BY 3; -- 按第3列(合计销售金额)升序(默认)
模拟结果:返回合计销售金额最低的5组记录(书号、书名、合计金额)。
9. 查询结果排序(升序/降序)
功能说明:按指定列对查询结果排序。
基础语法:SELECT 列名 FROM 表名 ORDER BY 列名1 [ASC/DESC], 列名2 [ASC/DESC], ...;
| 模拟数据(tb_employee05表): |
员工ID |
姓名 |
工资 |
奖金 |
| 1 |
A |
5000 |
1000 |
| 2 |
B |
6000 |
800 |
| 3 |
C |
5000 |
1200 |
-- 示例:按工资升序、奖金升序排列
SELECT *
FROM tb_employee05
ORDER BY 工资 ASC, 奖金 ASC; -- ASC可省略
| 模拟结果: |
员工ID |
姓名 |
工资 |
奖金 |
| 1 |
A |
5000 |
1000 |
| 3 |
C |
5000 |
1200 |
| 2 |
B |
6000 |
800 |
10. 按姓名首字母排序
功能说明:按某列的第一个字符排序。
基础语法:使用函数 SUBSTRING(列名, 起始位置, 长度) 截取首字符。
| 模拟数据(tb_abstu05表): |
学生ID |
姓名 |
国籍 |
| 1 |
张三 |
中国 |
| 2 |
李四 |
美国 |
| 3 |
王五 |
日本 |
-- 示例:按国籍的第一个字符升序排列
SELECT *
FROM tb_abstu05
ORDER BY SUBSTRING(国籍, 1, 1); -- 从第1个字符开始取1个
模拟结果(按国籍首字符排序):'中'(Z)、'美'(M)、'日'(R) -> 按拼音排序?实际按字符编码排序(如UTF-8): 中(中文字符编码较大), 美(M), 日(R)。
注意:中文字符排序与数据库的排序规则设置有关,此处按常规理解为按国籍的拼音首字母或Unicode值排序。
实际应用中,若需按拼音排序,可使用 COLLATE 指定排序规则(如Chinese_PRC_CI_AS)。
11. 按姓氏笔画排序
功能说明:按姓名的笔画数排序。
基础语法:在ORDER BY子句中使用 COLLATE 指定笔画排序规则。
| 模拟数据(tb_stu05表): |
学生ID |
姓名 |
| 1 |
张三 |
| 2 |
李四 |
| 3 |
王五 |
-- 示例:按姓名笔画升序排列
SELECT *
FROM tb_stu05
ORDER BY 姓名 COLLATE Chinese_PRC_Stroke_CI_AS_KS_WS; -- 笔画排序规则
模拟结果:按姓名的笔画数从少到多排列(实际笔画:张(11画)、李(7画)、王(4画))-> 王、李、张。
12. 多条件查询(NOT、OR)
功能说明:使用逻辑运算符组合多个条件。
基础语法:WHERE NOT 条件1 OR 条件2
| 模拟数据(tb_stuscore表): |
ID |
Name |
Math_Score |
Music_Score |
| 1 |
A |
85 |
90 |
| 2 |
B |
95 |
92 |
| 3 |
C |
88 |
96 |
-- 示例:查询数学成绩不大于90(即小于等于90)或者音乐成绩大于等于95的记录
SELECT ID, Name, Math_Score, Music_Score
FROM tb_stuscore
WHERE NOT (Math_Score > 90) OR (Music_Score >= 95);
-- 等价于:Math_Score <= 90 OR Music_Score >= 95
模拟结果:
- A:85<=90 -> 满足
- B:95>90 -> 不满足第一个条件,但音乐92<95 -> 不满足
- C:88<=90 -> 满足(且音乐96>=95也满足)
返回A和C的记录。
13. 区间查询(使用LIKE)
功能说明:使用LIKE进行模式匹配实现区间查询(适用于特定区间)。
基础语法:WHERE 列名 LIKE '模式' (如十位是8,个位任意:'8_')
| 模拟数据(tb_StuScore表): |
ID |
Math_score |
| 1 |
85 |
| 2 |
92 |
| 3 |
88 |
-- 示例:查询数学成绩在80-89之间的记录(即十位是8,个位0-9)
SELECT *
FROM tb_StuScore
WHERE Math_score LIKE '8_';
注意:此方法要求Math_score是字符串类型。如果Math_score是数值类型,可转换为字符串:CAST(Math_score AS VARCHAR) LIKE '8_'。
模拟结果:返回85和88的记录(92不在80-89之间)。
14. 不在90-99之间(使用LIKE)
功能说明:使用LIKE模式匹配查询不在某个区间的记录。
基础语法:使用 [^] 排除字符。
模拟数据(tb_StuScore表):同上表。
-- 示例:查询数学成绩不在90-99之间的记录
SELECT *
FROM tb_StuScore
WHERE
Math_score LIKE '[^9]%' -- 十位不是9,个位匹配任意数量(包括0个)的任意字符,即后续字符可以是任意内容
OR Math_score LIKE '[0-8]%' -- 或者十位是0-8(即0-89)
-- 注意:这里的模式不够精确,示例仅供参考。实际推荐使用数值比较:Math_score < 90 OR Math_score > 99
| 模拟结果(按上述SQL模式): |
数值 |
转换为字符串 |
是否匹配 [^9]% |
是否匹配 [0-8]% |
最终结果 |
| 85 |
'85' |
✅ 第一位是8≠9 |
✅ 第一位是8∈[0-8] |
✅ |
| 92 |
'92' |
❌ 第一位是9 |
❌ 第一位是9∉[0-8] |
❌ |
| 88 |
'88' |
✅ 第一位是8≠9 |
✅ 第一位是8∈[0-8] |
✅ |
返回85和88。
15. 查询姓姚的人
功能说明:查询以特定字符开头的数据。
基础语法:WHERE 列名 LIKE '姚%'
| 模拟数据(tb_StuScore表): |
ID |
姓名 |
... |
| 1 |
姚大 |
... |
| 2 |
李二 |
... |
| 3 |
姚远 |
... |
-- 示例:查询姓姚的记录
SELECT *
FROM tb_StuScore
WHERE 姓名 LIKE '姚%';
模拟结果:返回姚大和姚远的记录。
16. 去重
功能说明:返回指定列的唯一值(去除重复行)。
基础语法:SELECT DISTINCT 列名1, 列名2, ... FROM 表名;
| 模拟数据(tb_BookSell表): |
书号 |
书名 |
作者 |
出版社 |
| B001 |
书A |
作者A |
出版社A |
| B001 |
书A |
作者A |
出版社A |
| B002 |
书B |
作者B |
出版社B |
-- 示例:查询去重后的书号、书名、作者、出版社
SELECT DISTINCT 书号, 书名, 作者, 出版社
FROM tb_BookSell
ORDER BY 书号;
模拟结果:返回去重后的书号记录(B001只出现一次,B002出现)。
17. 列出重复超过1次的记录
功能说明:分组后使用HAVING筛选重复组。
基础语法:GROUP BY 列名 HAVING COUNT(列名) > 1
| 模拟数据(tb_Booksell表): |
销售ID |
书名 |
书号 |
作者 |
| 1 |
书A |
B001 |
作者A |
| 2 |
书A |
B001 |
作者A |
| 3 |
书B |
B002 |
作者B |
-- 示例:查询书名、书号、作者重复出现次数超过1次的记录,并统计重复数量
SELECT 书名, 书号, 作者, COUNT(书名) AS 重复数量
FROM tb_Booksell
GROUP BY 书名, 书号, 作者
HAVING COUNT(书名) >= 2;
模拟结果:返回书A的记录,重复数量为2。
18. 查询备注不为空的信息
功能说明:筛选指定列非空的记录。
基础语法:WHERE 列名 IS NOT NULL
| 模拟数据(tb_stu表): |
学生姓名 |
所在学院 |
备注 |
| 张三 |
计算机 |
NULL |
| 姚远 |
数学 |
转专业 |
-- 示例:查询备注不为空的学生姓名、所在学院、备注
SELECT 学生姓名, 所在学院, 备注
FROM tb_stu
WHERE 备注 IS NOT NULL;
模拟结果:返回姚远的记录(备注为“转专业”)。
19. 格式化信息(字符串连接)
功能说明:将多个列值格式化为一个字符串。
基础语法:使用 + 连接字符串(SQL Server)或 CONCAT 函数(跨数据库)。
| 模拟数据(tb_stu表): |
id |
Name |
| 1 |
张三 |
| 2 |
李四 |
-- 示例:格式化为'*姓名:张三;编号:1'的形式
SELECT '*姓名:' + Name + ';编号:' + CONVERT(VARCHAR(3), id) AS 学生信息
FROM tb_stu;
| 模拟结果: |
学生信息 |
| *姓名:张三;编号:1 |
| *姓名:李四;编号:2 |
20. 去除空格
功能说明:去除字符串左右的空格。
基础语法:
LTRIM(字符串):去除左侧空格。
RTRIM(字符串):去除右侧空格。
- 组合:
LTRIM(RTRIM(字符串)):去除左右空格。
| 模拟数据(客户信息表): |
姓名 |
| " 张三 " |
| "李四" |
-- 示例:去除姓名左右两边的空格
SELECT
姓名,
LTRIM(姓名) AS 去除左面空格,
RTRIM(姓名) AS 去除右面空格,
LTRIM(RTRIM(姓名)) AS 去除左右面空格
FROM 客户信息表;
| 模拟结果(假设输入有空格): |
姓名 |
去除左面空格 |
去除右面空格 |
去除左右面空格 |
| " 张三 " |
"张三 " |
" 张三" |
"张三" |
| "李四" |
"李四" |
"李四" |
"李四" |
21. 四舍五入
功能说明:对数值进行四舍五入处理。
基础语法:
ROUND(数值, 小数位数):四舍五入到指定小数位。
ROUND(数值, 负数):四舍五入到整数位(如十位、百位)。
CAST(表达式 AS 数据类型):转换数据类型(如REAL)。
| 模拟数据(工资表): |
人员姓名 |
代扣税 |
本月扣零 |
应发合计 |
| 张三 |
123.45 |
678.90 |
7890.123 |
-- 示例:代扣税四舍五入到十位(即个位四舍五入),本月扣零四舍五入到整数,应发合计保留1位小数并转为REAL类型
SELECT
人员姓名,
ROUND(代扣税, -1) AS 代扣税, -- 四舍五入到十位(如123.45 -> 120.00)
ROUND(本月扣零, 0) AS 本月扣零, -- 四舍五入到整数(678.90 -> 679.00)
CAST(ROUND(应发合计, 1) AS REAL) AS 应发合计 -- 保留1位小数,并转为REAL类型
FROM 工资表;
| 模拟结果: |
人员姓名 |
代扣税 |
本月扣零 |
应发合计 |
| 张三 |
120 |
679 |
7890.1 |
-- 假设7890.123四舍五入到1位小数:7890.1
总结
通过以上 21 个实例,我们系统地涵盖了 SQL 基础查询的核心操作。从最基础的列选择、别名设置,到灵活的条件筛选(区间、模糊、多条件)、数据排序(升序、降序、特殊规则)、聚合去重,再到数据的格式化与清理(连接字符串、去除空格、数值舍入),这些都是日常数据操作中最高频使用的技能。
掌握这些基础,你就能独立应对大部分简单的数据查询与分析任务。当然,SQL 的世界远不止于此,更复杂的多表连接、子查询、窗口函数等高级特性,将帮助你解锁更深层次的数据洞察力。如果你想深入学习更多关于 MySQL 及其他数据库的高级技巧,欢迎在云栈社区继续探索与交流。