SQL WHERE 子句(长文讲解)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
什么是 SQL WHERE 子句?
在 SQL(结构化查询语言)的世界中,WHERE 子句如同一个精准的“数据过滤器”。它允许开发者根据特定条件筛选数据库中的记录,仅返回符合条件的数据。无论是查询某个用户的订单、统计特定时间段内的销售数据,还是分析满足复杂条件的业务指标,WHERE 子句都是实现这些目标的核心工具。
想象你在一个图书馆中寻找书籍,WHERE 子句的作用就像“书目检索系统”——你可以通过输入作者、书名、出版日期等条件,快速定位到目标书籍,而不是翻遍所有书架。SQL WHERE 子句在数据库中的角色也是如此,它帮助开发者高效地从海量数据中提取所需信息。
SQL WHERE 子句的基础语法
基本结构
WHERE 子句通常位于 SQL 查询的 SELECT 语句之后,其基本语法如下:
SELECT 列名1, 列名2, ...
FROM 表名
WHERE 条件表达式;
例如,查询所有年龄大于 30 岁的用户:
SELECT name, age
FROM users
WHERE age > 30;
这里的 age > 30
是条件表达式,只有满足该条件的记录才会被返回。
条件表达式的核心要素
条件表达式由以下部分组成:
- 列名:要比较的数据库字段(如
age
)。 - 运算符:定义比较规则(如
>
、=
、LIKE
)。 - 值:与列值进行比较的具体数值或字符串(如
30
、'上海'
)。
常用的比较运算符
等于(=)与不等于(!= 或 <>)
-
等于(=):查询与指定值完全匹配的记录。
SELECT * FROM orders WHERE status = 'completed';
该语句将返回所有状态为
completed
的订单。 -
不等于(!= 或 <>):筛选不满足条件的记录。
SELECT * FROM products WHERE price <> 100;
这里会排除价格为 100 的商品。
大于(>)、小于(<)、大于等于(>=)、小于等于(<=)
这些运算符用于数值或日期的范围筛选:
-- 查询价格高于 500 的商品
SELECT product_name, price
FROM products
WHERE price > 500;
-- 查询 2023 年 1 月 1 日之后创建的订单
SELECT order_id, created_at
FROM orders
WHERE created_at > '2023-01-01';
逻辑运算符:AND、OR、NOT
组合多个条件:AND
当需要同时满足多个条件时,使用 AND 运算符:
SELECT name, salary
FROM employees
WHERE department = 'Sales' AND salary > 50000;
此语句将筛选出“销售部门”且“薪资高于 50000”的员工。
满足任一条件:OR
OR 允许筛选满足至少一个条件的记录:
SELECT *
FROM customers
WHERE country = 'China' OR country = 'Japan';
该查询返回来自中国或日本的客户。
反向筛选:NOT
NOT 可逆向条件逻辑:
SELECT *
FROM users
WHERE NOT (status = 'inactive');
此语句将排除状态为 inactive
的用户。
字符串匹配:LIKE 和通配符
使用 LIKE 进行模糊查询
LIKE 运算符结合通配符(如 %
和 _
),可以实现灵活的字符串匹配:
%
:匹配任意长度的字符序列。_
:匹配单个字符。
示例 1:以“Apple”开头的商品
SELECT product_name
FROM products
WHERE product_name LIKE 'Apple%';
示例 2:查找姓氏为“李”且名字为两个字的用户
SELECT name
FROM users
WHERE name LIKE '李_';
区分大小写(可选)
某些数据库(如 PostgreSQL)支持 ILIKE
实现不区分大小写的模糊匹配:
SELECT *
FROM articles
WHERE title ILIKE '%SQL%';
日期与时间条件:精准筛选
直接比较日期
直接指定日期值进行筛选:
SELECT order_id, created_at
FROM orders
WHERE created_at BETWEEN '2023-01-01' AND '2023-12-31';
使用日期函数
结合日期函数(如 CURDATE()
、DATE_SUB()
)实现动态条件:
-- 查询最近一周的订单
SELECT *
FROM orders
WHERE created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY);
高级用法:IN、BETWEEN 和 NULL 处理
IN:多值匹配
IN 允许一次性指定多个可能的值:
SELECT department, AVG(salary)
FROM employees
WHERE department IN ('Engineering', 'Marketing')
GROUP BY department;
此查询计算工程和市场部门的平均薪资。
BETWEEN:区间筛选
BETWEEN 简化了范围条件的书写:
SELECT *
FROM products
WHERE price BETWEEN 200 AND 500;
等价于 price >= 200 AND price <= 500
。
处理 NULL 值
使用 IS NULL 或 IS NOT NULL 筛选空值:
-- 查询未填写邮箱的用户
SELECT *
FROM users
WHERE email IS NULL;
性能优化:WHERE 子句与索引
索引的重要性
WHERE 子句的性能高度依赖数据库索引。例如:
-- 假设 `user_id` 列有索引
SELECT *
FROM orders
WHERE user_id = 123;
此查询会快速定位到用户 123 的订单,因为索引避免了全表扫描。
避免全表扫描的陷阱
以下条件可能因缺乏索引导致性能下降:
-- 非法使用函数可能导致索引失效
SELECT *
FROM users
WHERE LOWER(email) = 'example@example.com';
更好的写法是:
SELECT *
FROM users
WHERE email = 'example@example.com';
常见错误与注意事项
1. 忽略 NULL 值的特殊性
-- 错误:无法直接比较 NULL
SELECT *
FROM users
WHERE age = NULL; -- 应使用 `age IS NULL`
2. 运算符优先级问题
-- 错误:`AND` 的优先级高于 `OR`
SELECT *
FROM products
WHERE category = 'Electronics' OR price < 100 AND in_stock = true;
-- 正确写法:添加括号明确优先级
SELECT *
FROM products
WHERE (category = 'Electronics' OR price < 100) AND in_stock = true;
3. SQL 注入风险
动态拼接 SQL 语句时需谨慎,避免注入攻击:
-- 危险写法(示例)
query = "SELECT * FROM users WHERE username = '" + user_input + "';"
-- 安全写法(使用参数化查询)
query = "SELECT * FROM users WHERE username = ?";
execute_query(query, [user_input]);
结论
SQL WHERE 子句是开发者与数据库交互的核心工具,它通过灵活的条件表达式帮助开发者精准筛选数据。从基础的等值查询到复杂的逻辑组合,掌握 WHERE 子句的使用不仅能提升开发效率,还能为数据驱动的决策提供可靠支持。
无论是初学者还是中级开发者,建议通过实际案例反复练习 WHERE 子句的用法,并结合索引优化查询性能。随着对 SQL 理解的深入,WHERE 子句将逐渐成为你解决业务问题的“瑞士军刀”,在数据分析、报表生成、实时查询等场景中发挥关键作用。
提示:尝试将本文中的代码示例在本地数据库中运行,观察不同条件下的结果差异,这是掌握 SQL 最有效的学习方法。