数据过滤是 SQL 查询的核心技能。通过 WHERE 子句,可以精确筛选出符合条件的数据,减少不必要的数据传输,提升查询效率。
| 运算符 | 含义 | 示例 |
|---|---|---|
| = | 等于 | score = 80 |
| <> 或 != | 不等于 | score <> 80 |
| < | 小于 | score < 80 |
| <= | 小于等于 | score <= 80 |
| > | 大于 | score > 80 |
| >= | 大于等于 | score >= 80 |
| 运算符 | 含义 | 示例 |
|---|---|---|
| BETWEEN | 在范围内 | score BETWEEN 80 AND 90 |
| IS NULL | 为空值 | score IS NULL |
| IS NOT NULL | 非空值 | score IS NOT NULL |
注意:不同 DBMS 支持的运算符可能不同。MySQL 不支持
!>和!<,Access 不支持!=。
-- 查询最大生命值大于 6000 的英雄
SELECT name, hp_max FROM heros WHERE hp_max > 6000;
-- 查询最大生命值在 5399 到 6811 之间的英雄(包含边界值)
SELECT name, hp_max FROM heros WHERE hp_max BETWEEN 5399 AND 6811;
-- 查询最大生命值为空的英雄
SELECT name, hp_max FROM heros WHERE hp_max IS NULL;
-- 查询最大生命值不为空的英雄
SELECT name, hp_max FROM heros WHERE hp_max IS NOT NULL;AND 用于组合多个条件,所有条件都必须满足:
-- 查询最大生命值 > 6000 且最大法力 > 1700 的英雄
SELECT name, hp_max, mp_max
FROM heros
WHERE hp_max > 6000 AND mp_max > 1700
ORDER BY (hp_max + mp_max) DESC;OR 用于组合多个条件,满足任意一个条件即可:
-- 查询最大生命值+最大法力值 > 8000 或(最大生命值 > 6000 且最大法力 > 1700)
SELECT name, hp_max, mp_max
FROM heros
WHERE (hp_max + mp_max) > 8000 OR (hp_max > 6000 AND mp_max > 1700)
ORDER BY (hp_max + mp_max) DESC;NOT 用于否定条件:
-- 查询不是法师的英雄
SELECT name, role_main FROM heros WHERE NOT role_main = '法师';
-- 等价于
SELECT name, role_main FROM heros WHERE role_main <> '法师';IN 用于匹配一组值中的任意一个:
-- 查询主要定位是法师或射手的英雄
SELECT name, role_main
FROM heros
WHERE role_main IN ('法师', '射手');优先级从高到低:() > NOT > AND > OR
-- 示例 1:AND 优先于 OR
-- 解析为:hp_max > 6000 OR (mp_max > 1700 AND name = '张飞')
SELECT name, hp_max, mp_max
FROM heros
WHERE hp_max > 6000 OR mp_max > 1700 AND name = '张飞';
-- 示例 2:使用括号改变优先级
-- 解析为:(hp_max > 6000 OR mp_max > 1700) AND name = '张飞'
SELECT name, hp_max, mp_max
FROM heros
WHERE (hp_max > 6000 OR mp_max > 1700) AND name = '张飞';-- 查询主要定位或次要定位是法师或射手,且上线时间不在 2016-01-01 到 2017-01-01 之间的英雄
SELECT name, role_main, role_assist, hp_max, mp_max, birthdate
FROM heros
WHERE (role_main IN ('法师', '射手') OR role_assist IN ('法师', '射手'))
AND DATE(birthdate) NOT BETWEEN '2016-01-01' AND '2017-01-01'
ORDER BY (hp_max + mp_max) DESC;LIKE 操作符与通配符配合使用,实现模糊匹配。
% 匹配任意字符出现任意次数(包括 0 次):
-- 查询名字中包含"太"字的英雄
SELECT name FROM heros WHERE name LIKE '%太%';
-- 结果:太乙真人、东皇太一
-- 查询以"张"开头的英雄
SELECT name FROM heros WHERE name LIKE '张%';
-- 结果:张飞、张良
-- 查询以"飞"结尾的英雄
SELECT name FROM heros WHERE name LIKE '%飞';
-- 结果:张飞_ 匹配单个字符:
-- 查询名字第二个字是"太"的英雄
SELECT name FROM heros WHERE name LIKE '_太%';
-- 结果:东皇太一(太乙真人的"太"是第一个字,不匹配)| 通配符 | 含义 | 示例 |
|---|---|---|
| % | 匹配任意数量字符 | LIKE '%太%' 匹配包含"太" |
| _ | 匹配单个字符 | LIKE '_太%' 匹配第二个字是"太" |
% 开头的 LIKE 查询会导致索引失效-- 索引有效
SELECT name FROM heros WHERE name LIKE '张%';
-- 索引失效(全表扫描)
SELECT name FROM heros WHERE name LIKE '%张';
SELECT name FROM heros WHERE name LIKE '%张%';-- 可能匹配不到 'LIU BEI'
SELECT name FROM heros WHERE name LIKE 'liu%';
-- 强制区分大小写
SELECT name FROM heros WHERE name LIKE BINARY 'liu%';NULL 表示"未知"或"不存在",不等于任何值,包括 NULL 本身:
-- 错误:不能使用 = 判断 NULL
SELECT name FROM heros WHERE hp_max = NULL; -- 错误!
-- 正确:使用 IS NULL
SELECT name FROM heros WHERE hp_max IS NULL;
-- 正确:使用 IS NOT NULL
SELECT name FROM heros WHERE hp_max IS NOT NULL;-- COUNT(*) 计算所有行,包括 NULL
SELECT COUNT(*) FROM heros;
-- COUNT(column) 忽略 NULL 值
SELECT COUNT(hp_max) FROM heros;
-- AVG、SUM、MAX、MIN 忽略 NULL 值
SELECT AVG(hp_max) FROM heros;-- MySQL 使用 <=> 安全等于运算符
SELECT name FROM heros WHERE hp_max <=> NULL;
-- 使用 COALESCE 提供默认值
SELECT name, COALESCE(hp_max, 0) AS hp FROM heros;
-- 使用 IFNULL 提供默认值(MySQL)
SELECT name, IFNULL(hp_max, 0) AS hp FROM heros;-- 查询特定日期
SELECT name, birthdate FROM heros WHERE birthdate = '2016-03-24';
-- 查询日期范围
SELECT name, birthdate FROM heros WHERE birthdate BETWEEN '2016-01-01' AND '2016-12-31';
-- 使用日期函数
SELECT name, birthdate FROM heros WHERE YEAR(birthdate) = 2016;
SELECT name, birthdate FROM heros WHERE DATE(birthdate) = '2016-03-24';-- 精确匹配
SELECT name FROM heros WHERE name = '张飞';
-- 大小写不敏感
SELECT name FROM heros WHERE LOWER(name) = 'zhang fei';
-- 去除空格后匹配
SELECT name FROM heros WHERE TRIM(name) = '张飞';-- 整数比较
SELECT name, hp_max FROM heros WHERE hp_max > 6000;
-- 浮点数比较(注意精度问题)
SELECT name, height FROM player WHERE height BETWEEN 1.90 AND 2.00;
-- 使用 ROUND 处理精度
SELECT name, height FROM player WHERE ROUND(height, 2) = 1.93;-- 好:选择性高的列(值分布分散)
SELECT * FROM heros WHERE name = '张飞';
-- 差:选择性低的列(值分布集中)
SELECT * FROM heros WHERE role_main = '战士';-- 差:索引失效
SELECT name FROM heros WHERE YEAR(birthdate) = 2016;
-- 好:使用范围查询
SELECT name FROM heros
WHERE birthdate >= '2016-01-01' AND birthdate < '2017-01-01';-- IN 适合子查询结果集较小的情况
SELECT name FROM heros
WHERE role_main IN ('法师', '射手', '战士');
-- EXISTS 适合子查询需要关联外部表的情况
SELECT name FROM heros h1
WHERE EXISTS (
SELECT 1 FROM heros h2
WHERE h2.role_main = h1.role_main
AND h2.hp_max > 7000
);-- 好:只查询索引列
SELECT id, name FROM heros WHERE name LIKE '张%';
-- 差:查询非索引列
SELECT * FROM heros WHERE name LIKE '张%';| 类型 | 运算符 |
|---|---|
| 比较 | =, <>, !=, <, <=, >, >= |
| 范围 | BETWEEN, IN |
| 空值 | IS NULL, IS NOT NULL |
| 模糊 | LIKE |
| 运算符 | 含义 | 优先级 |
|---|---|---|
| NOT | 非 | 高 |
| AND | 与 | 中 |
| OR | 或 | 低 |
| 通配符 | 含义 |
|---|---|
| % | 任意数量字符 |
| _ | 单个字符 |