WHERE 子句是 SQL 查询中用于过滤记录的核心部分,它后面紧跟一个或多个条件,这些条件共同定义了哪些行应该被包含在查询结果中。
WHERE 的“参数”就是条件表达式。
WHERE 子句的基本语法
SELECT column1, column2, ... FROM table_name WHERE condition;
SELECT ... FROM table_name: 指定要从哪个表查询哪些列。WHERE condition: 这是过滤的关键。condition就是我们所说的“参数”,它必须是一个返回TRUE、FALSE或UNKNOWN的表达式。
WHERE 子句中的“参数”(条件)详解
WHERE 的参数非常灵活,可以是简单的比较,也可以是复杂的逻辑组合,我们将其分为几大类:
A. 比较运算符
这是最常用的条件类型,用于比较列的值和常量、表达式或另一个列的值。
| 运算符 | 描述 | 示例 |
|---|---|---|
| 等于 | WHERE name = 'John' |
|
或 <> |
不等于 | WHERE salary != 5000 |
> |
大于 | WHERE age > 30 |
< |
小于 | WHERE score < 60 |
>= |
大于或等于 | WHERE experience >= 5 |
<= |
小于或等于 | WHERE price <= 100 |
BETWEEN ... AND ... |
在一个范围内(包含两端) | WHERE age BETWEEN 20 AND 30 |
IN (value1, value2, ...) |
在一个指定的值列表中 | WHERE department IN ('HR', 'IT', 'Sales') |
LIKE |
进行通配符匹配 | WHERE name LIKE 'J%' |
IS NULL |
为 NULL 值 |
WHERE phone_number IS NULL |
IS NOT NULL |
不为 NULL 值 |
WHERE phone_number IS NOT NULL |
示例:
-- 查找年龄大于30岁的员工
SELECT * FROM employees WHERE age > 30;
-- 查找薪资在5000到10000之间的员工
SELECT * FROM employees WHERE salary BETWEEN 5000 AND 10000;
-- 查找在 'HR' 或 'IT' 部门的员工
SELECT * FROM employees WHERE department IN ('HR', 'IT');
-- 查找所有姓 '张' 的员工
SELECT * FROM employees WHERE name LIKE '张%';
B. 逻辑运算符
当需要组合多个条件时,可以使用逻辑运算符。
| 运算符 | 描述 | 示例 |
|---|---|---|
AND |
逻辑与:所有条件都必须为 TRUE |
WHERE age > 30 AND department = 'IT' |
OR |
逻辑或:任一条件为 TRUE 即可 |
WHERE department = 'HR' OR salary > 8000 |
NOT |
逻辑非:反转条件的含义 | WHERE NOT department = 'Sales' 或 WHERE department NOT IN ('Sales') |
示例:
-- 查找年龄大于30岁并且在IT部门的员工 SELECT * FROM employees WHERE age > 30 AND department = 'IT'; -- 查找薪资高于8000或者在HR部门的员工 SELECT * FROM employees WHERE salary > 8000 OR department = 'HR'; -- 查找所有不在 'Sales' 部门的员工 SELECT * FROM employees WHERE NOT department = 'Sales';
注意运算符优先级:
AND 的优先级高于 OR,建议使用 来明确逻辑关系,避免混淆。
-- 查找在IT部门且薪资>8000,或者在HR部门的员工 -- 使用括号确保逻辑正确 SELECT * FROM employees WHERE (department = 'IT' AND salary > 8000) OR department = 'HR';
C. 其他常用操作符
除了比较和逻辑运算符,还有一些强大的操作符可以用于 WHERE 子句。
| 操作符 | 描述 | 示例 |
|---|---|---|
REGEXP 或 RLIKE |
正则表达式匹配 | WHERE email REGEXP '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$' |
INFORMATION_SCHEMA |
查询元数据(如检查表是否存在) | SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'your_database_name' |
EXISTS |
检查子查询是否返回任何行 | SELECT * FROM employees e WHERE EXISTS (SELECT 1 FROM salaries s WHERE s.employee_id = e.id) |
WHERE 子句的注意事项
-
对
NULL值的处理:NULL表示“未知”或“缺失”,它不等于 0、空字符串 或另一个NULL。- 必须使用
IS NULL或IS NOT NULL来检查NULL值,不能使用= NULL或!= NULL。-- 正确:查找没有电话号码的客户 SELECT * FROM customers WHERE phone_number IS NULL;
-- 错误:这样写查不到任何结果 -- SELECT * FROM customers WHERE phone_number = NULL;
-
LIKE通配符:- 匹配任意数量的字符(包括零个字符)。
_:匹配单个任意字符。- 如果你想匹配包含 或
_的字面字符,需要使用\进行转义。-- 查找所有以 'A' 开头的名字 WHERE name LIKE 'A%';
-- 查找第二个字母是 'o' 的名字 WHERE name LIKE '_o%';
-- 查找包含 '100%' 的描述 WHERE description LIKE '%100\%%';
-
性能优化:
- 索引:在
WHERE子句中频繁使用的列上创建索引可以极大地提高查询速度。WHERE user_id = 123中的user_id列非常适合建索引。 - 避免在索引列上使用函数:像
WHERE UPPER(name) = 'JOHN'这样的查询会使得索引失效,因为函数作用于列值上,更好的做法是确保数据存储时就是统一的大小写,或者使用全文索引等更高级的技术。
- 索引:在
-
引号的使用:
- 字符串:必须用单引号 或双引号 括起来,在 MySQL 中,标准做法是使用单引号。
- 数字:不需要引号。
- 列名和表名:通常不需要引号,但如果名称是保留关键字或包含特殊字符(如空格),则需要用反引号
`括起来。
综合示例
假设我们有一个 products 表,结构如下:
id, name, category, price, stock_quantity
-- 1. 查找价格小于100且库存大于50的电子产品
SELECT * FROM products
WHERE price < 100 AND stock_quantity > 50 AND category = 'Electronics';
-- 2. 查找类别为 'Books' 或 'Toys' 的产品
SELECT * FROM products
WHERE category IN ('Books', 'Toys');
-- 3. 查找名称中包含 "Pro" 且价格在50到200之间的产品
SELECT * FROM products
WHERE name LIKE '%Pro%' AND price BETWEEN 50 AND 200;
-- 4. 查找所有非电子产品,并且价格不为NULL的产品
SELECT * FROM products
WHERE category != 'Electronics' AND price IS NOT NULL;
WHERE 子句的“参数”就是条件表达式,它由比较运算符(, >, LIKE 等)、逻辑运算符(AND, OR, NOT)以及列名、常量等组成,通过灵活组合这些元素,你可以从海量数据中精确地筛选出你需要的信息,理解并正确使用 WHERE 是掌握 SQL 查询的关键一步。
