一、单表查询
1.1基本语法
SELECT [DISTINCT] * | {column1,colunm2,column3......}
FROM table_name
①SELECT指定查询那些列。
②column指定列(字段)名。
③*号代表查询所有列(字段)。
④FROM指定查询那张表
⑤DISTINCT可选,指显示结果时,是否去重。且查询出的记录中所有的字段都相同,才会去重。
1.2使用表达式对查询的结果进行运算。
SELECT * | {column1|expression,column2|expression,column3|expression......}
FROM table_name
1.3在SELECT语句中可使用as语句对查询出的字段取别名。
SELECT column_name as another_name
FROM table_name
1.4使用WHERE子句进行条件查询
SELECT * FROM table_name
WHERE where_definition
1.4.1在WHERE子句中常用的运算符
比较运算符 |
><= <= >= <>|(!=) |
大于 ,小于, 等于, 小于等于, 大于等于, 不等于(两种写法) |
BETWEEN...AND... |
显示在某一区间的值 | |
IN(set) |
显示在某一集合中的值 | |
LIKE NOT LIKE |
模糊查询 模糊查询 | |
IS NULL |
判断是否为空 | |
逻辑运算符 |
and |
多个条件同时成立 |
or |
多个条件任一成立 | |
not |
条件不成立 |
1.4.2模糊查询的通配符
在 SQL 中,模糊查询是一种用于匹配不精确或部分数据的查询方式,通常用于文本字段(如 VARCHAR
、TEXT
)。它允许你查找包含特定模式的字符串,而不是精确匹配整个值。
主要模糊查询操作符
(1). LIKE
操作符
用于匹配字符串模式,支持两种通配符:
%
:匹配任意数量(包括零个)的任意字符。_
(下划线):匹配单个任意字符。
示例:
-- 查询姓"张"的学生
SELECT * FROM students WHERE name LIKE '张%';
-- 查询名字是两个字且第二个字是"三"的学生
SELECT * FROM students WHERE name LIKE '_三';
-- 查询名字中包含"四"的学生
SELECT * FROM students WHERE name LIKE '%四%';
(2). NOT LIKE
操作符
与 LIKE
相反,用于排除匹配特定模式的记录。
-- 查询名字不姓"张"的学生
SELECT * FROM students WHERE name NOT LIKE '张%';
(3). ILIKE
操作符(部分数据库支持,如 PostgreSQL)
与 LIKE
类似,但不区分大小写。
-- 查询名字包含"john"的学生(不区分大小写)
SELECT * FROM students WHERE name ILIKE '%john%';
(4).通配符详解
%
(百分号):
-- 匹配以"张"开头的任意字符串
WHERE name LIKE '张%';
-- 匹配以"三"结尾的任意字符串
WHERE name LIKE '%三';
-- 匹配包含"中"的任意字符串
WHERE name LIKE '%中%';
_
(下划线):
-- 匹配第二位是"三"的两个字符的名字(如"张三")
WHERE name LIKE '_三';
-- 匹配第三位是"a"的三个字符的名字(如"XaY")
WHERE name LIKE '__a';
(5).结合 ESCAPE
处理特殊字符
如果你需要在模式中匹配实际的通配符(如 %
或 _
),可以使用 ESCAPE
关键字定义转义字符。
-- 查询名字中包含"_%_"的学生(使用"\"作为转义字符)
SELECT * FROM students WHERE name LIKE '%\_%\_%' ESCAPE '\';
(6).性能注意事项
- 前置通配符影响性能:
以%
开头的模式(如LIKE '%张'
)无法使用索引,可能导致全表扫描。
✅ 优化建议:尽量使用LIKE '张%'
而非LIKE '%张'
。 - 索引优化:
如果经常进行模糊查询,可以考虑在查询字段上创建索引。例如:
CREATE INDEX idx_name ON students (name);
(7).替代方案
①. REGEXP
(正则表达式)
更强大的模式匹配,但性能可能较差。
-- 查询名字以"张"或"李"开头的学生
SELECT * FROM students WHERE name REGEXP '^(张|李)';
②. 全文搜索(Full-Text Search)
适用于大型文本数据,支持更高效的搜索。例如 MySQL 的 MATCH AGAINST
:
-- 假设 `content` 字段已创建全文索引
SELECT * FROM articles WHERE MATCH(content) AGAINST ('关键词' IN NATURAL LANGUAGE MODE);
(8).常见应用场景
- 搜索功能(如电商平台的商品搜索)。
- 数据筛选(如查找包含特定关键词的文章)。
- 模糊匹配用户输入(如自动补全)。
(9).示例总结
-- 查询姓"王"且名字是两个字的学生
SELECT * FROM students WHERE name LIKE '王_';
-- 查询成绩备注中包含"优秀"的学生
SELECT * FROM students WHERE remark LIKE '%优秀%';
-- 查询邮箱以".com"结尾的用户
SELECT * FROM users WHERE email LIKE '%.com';
通过灵活使用通配符和操作符,你可以实现各种复杂的模糊查询需求。
1.5使用ORDER BY子句排序查询结果
SELECT colunm1,column2,column3...
FROM table_name
ORDER BY column_name asc|desc
①ORDER BY指定排序的列,排序的列可以是表中的列名,也可以是select语句后指定的列名。
②asc升序【默认】,desc降序
③ORDER BY子句应该位于SELECT语句的末尾。
1.6示例
#新建学生表,并且插入几条示例数据(故意重复一条数据)
CREATE TABLE students (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
chinese_score INT,
math_score INT,
english_score INT
);
INSERT INTO students (name, chinese_score, math_score, english_score) VALUES
('张三', 85, 92, 78),
('李四', 90, 87, 95),
('王五', 76, 88, 80),
('赵六', 94, 91, 89),
('张三', 85, 92, 78);
示例一:查询学生表的所有字段内容
#查询学生表的所有字段内容
SELECT * FROM `students`
示例二:查询学生表中的所有字段内容,并去重
#查询学生表的所有字段内容,并去重
SELECT DISTINCT * FROM `students`
可以看到实际查询的结果并没有去重,因为DISTINCT关键字存在时需要记录的所有字段都相同才会去重,而张三的两条记录的id是不同的。
ps:要对查询结果去重,你可以使用 DISTINCT
关键字。不过需要注意,DISTINCT
会对 整条记录 去重(即所有字段值都相同才算重复)。由于你的表中包含自增主键 id
,每条记录的 id
都是唯一的,因此直接使用 DISTINCT
不会有实际效果。
修改后的 SQL:
sql
-- 假设你想按姓名去重(保留每个姓名的第一条记录)
SELECT DISTINCT ON (name) *
FROM students
ORDER BY name, id; -- 按姓名排序,相同姓名按id排序,保留id最小的记录
-- 或者如果你只想查看不同的姓名
SELECT DISTINCT name
FROM students;
说明:
DISTINCT ON (列名)
(适用于 PostgreSQL):
只保留指定列(如name
)中值相同的第一条记录,需要配合ORDER BY
使用来确定保留哪条记录。SELECT DISTINCT 列名
:
返回指定列的唯一值,常用于统计有多少不同的姓名、性别等。
如果你使用的是 MySQL(不支持 DISTINCT ON
):
sql
-- 按姓名分组,取每组第一条记录的所有字段(需要 MySQL 8.0+)
WITH ranked_students AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY name ORDER BY id) AS rn
FROM students
)
SELECT *
FROM ranked_students
WHERE rn = 1;
注意:
- 如果你的表中没有真正的重复记录(即所有记录的
id
不同),使用DISTINCT
不会改变结果。 - 去重逻辑取决于你的业务需求,例如:
-
- 若想保留每个学生的最新成绩,可按
id
降序排列。 - 若只需查看有多少不同的学生姓名,直接用
SELECT DISTINCT name
。
- 若想保留每个学生的最新成绩,可按
示例三:统计每个学生的总分
#统计所有学生的总分
SELECT `name`,(chinese_score+math_score+english_score)
FROM `students`
示例四:统计每个学生所有总分再加十分的结果
#统计每个学生所有总分再加十分的结果
SELECT `name`,(chinese_score+math_score+english_score+10)
FROM `students`
示例五:使用别名来显示查询的每个学生的总分的结果
#使用别名来显示查询的每个学生的总分的结果
SELECT `name` AS '姓名',(chinese_score+math_score+english_score) AS '总分'
FROM `students`
示例六:查询李四的成绩
#查询李四的成绩
SELECT * FROM `students`
WHERE `name`='李四'
示例七:查询总分不等于三百的的学生的成绩
#查询总分不等于三百的的学生的成绩
SELECT * FROM `students`
WHERE (chinese_score+math_score+english_score)<>300
示例八:查询总分大于260的学生的成绩
#查询总分大于260的学生的成绩
SELECT * FROM `students`
WHERE (chinese_score+math_score+english_score)>260
示例九:查询语文成绩在(80,90,95)这个集合中的的学生的成绩
#查询语文成绩在(80,90,95)这个集合中的的学生的成绩
SELECT * FROM `students`
WHERE `chinese_score`IN(80,90,95)
示例十:查询姓张的同学的成绩
#查询姓张的同学的成绩
SELECT * FROM `students`
WHERE `name`LIKE'张%'
示例十一:查询姓张的名字为三个字的同学的成绩
#查询姓张的名字为三个字的同学的成绩
SELECT * FROM `students`
WHERE `name`LIKE'张__'
示例十二:查询所有学生的成绩,按数学成绩降序
#查询所有学生的成绩,按数学成绩降序
SELECT * FROM `students`
ORDER BY `math_score`DESC
示例十三:查询所有学生的成绩,按总分成绩降序
#查询所有学生的成绩,按总分成绩降序
SELECT * ,(chinese_score+math_score+english_score) AS 'total_score' FROM `students`
ORDER BY (chinese_score+math_score+english_score)DESC
示例十四:对姓张的同学的成绩进行按总分降序排序
#对姓张的同学的成绩进行按总分降序排序
SELECT * ,(chinese_score+math_score+english_score) AS 'total_score' FROM `students`
WHERE `name` LIKE '张%'
ORDER BY (chinese_score+math_score+english_score)DESC