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 是条件表达式,只有满足该条件的记录才会被返回。

条件表达式的核心要素

条件表达式由以下部分组成:

  1. 列名:要比较的数据库字段(如 age)。
  2. 运算符:定义比较规则(如 >=LIKE)。
  3. :与列值进行比较的具体数值或字符串(如 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 NULLIS 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 最有效的学习方法。

最新发布