SQL WHERE 详解:10 分钟内像专家一样过滤数据

SQL WHERE 详解:10 分钟内像专家一样过滤数据

用一个贴近生活的场景吸引读者:假设你有一个包含 1 千万条客户记录的数据库,但你只需要找到上个月购物金额超过 100 美元的纽约客户。如果没有 WHERE 子句,你就会被淹没在不相关的数据中。

WHERE 子句就是你的过滤器--从海量数据集中准确提取所需内容的精确工具。

在本 10 分钟指南中,你将掌握

  • 使用比较运算符进行基本过滤
  • 使用 AND、OR、NOT 组合条件
  • 使用 LIKE 进行模式匹配
  • 正确处理 NULL 值(初学者的头号错误)
  • 常见的 WHERE 子句陷阱以及如何避免这些陷阱

最后,您将自信地编写 WHERE 子句,并避免 90% 的 SQL 初学者都会犯的错误。

让我们深入学习。


什么是 WHERE 子句?

WHERE 子句根据指定条件过滤记录。将其视为质量控制检查点:只有符合条件的记录才能通过。

基本语法:

sql 复制代码
SELECT column1, column2
FROM table_name
WHERE condition;

**关键概念:**WHERE 会对每一行进行单独评估。如果条件为 "真",则结果中包含该行。如果条件为 FALSE 或 NULL,则将其排除在外。

执行顺序很重要:

  1. FROM - 识别表
  2. WHERE - 筛选记录
  3. SELECT - 选择列

这个顺序就是为什么不能在 WHERE 中引用列别名的原因(稍后将详细介绍)。


1.比较操作符:基本工具包

六个基本操作

每个 WHERE 子句都从这里开始:

等于 (=)

sql 复制代码
SELECT * FROM employees
WHERE department = 'Sales';

查找完全匹配。记住:文本使用单引号,数字不使用引号。

不等于 (<> 或 !=)

sql 复制代码
SELECT * FROM orders
WHERE status <> 'cancelled';

指定值以外的所有内容。

大于 (>) 和小于 (<)

sql 复制代码
SELECT * FROM products
WHERE price > 100;

SELECT * FROM students
WHERE age < 18;

大于/小于或等于 (>= 和 <=)

sql 复制代码
SELECT * FROM employees
WHERE salary >= 50000 AND salary <= 100000;

实用提示

**字符串:**始终使用单引号"文本",而不是双引号

数字: 在年龄 = 25 的情况下,不需要引号

✅**日期:**使用 ISO 格式WHERE hire_date >= "2025-01-01

常见错误: WHERE 类别 = 电子(缺少引号)

正确: WHERE 类别 = "电子产品


2.逻辑操作符:AND, OR, NOT

像专家一样组合条件

AND 运算符- 所有条件必须为真:

sql 复制代码
SELECT * FROM employees
WHERE department = 'Sales'
  AND salary > 50000
  AND hire_date >= '2020-01-01';

将 AND 运算符视为缩小结果范围:您是在堆叠要求。

OR 运算符- 至少一个条件必须为真:

sql 复制代码
SELECT * FROM employees
WHERE department = 'Sales'
   OR department = 'Marketing'
   OR department = 'HR';

OR 运算符扩大了结果范围:你接受了多种可能性。

NOT 运算符- 否定一个条件:

sql 复制代码
SELECT * FROM employees
WHERE NOT department = 'Sales';
-- Returns everyone except Sales

第一大陷阱:混合 AND/OR 而不加括号

❌ 这并不像预期的那样有效:

sql 复制代码
SELECT * FROM products
WHERE category = 'Electronics'
   OR category = 'Computers'
  AND price < 500;

**为什么?**AND 的优先级高于 OR。SQL 将其解释为

"所有电子产品(任何价格) OR(500 美元以下的电脑)

因此,你会在 "500 美元以下 "的结果中看到价值 5000 美元的笔记本电脑!

✅ 始终使用括号:

sql 复制代码
SELECT * FROM products
WHERE (category = 'Electronics' OR category = 'Computers')
  AND price < 500;

**黄金法则:**如果混合 AND/OR,请使用括号。Every.每次。每一次。


3.使用 LIKE 进行模式匹配

灵活搜索的通配符

当您不知道准确值时,可使用带有通配符的 LIKE:

百分号 (%) - 匹配零个或多个字符

sql 复制代码
-- Starts with 'John'
WHERE first_name LIKE 'John%'
-- Matches: John, Johnny, Johnson

-- Ends with 'son'
WHERE last_name LIKE '%son'
-- Matches: Johnson, Anderson, Wilson

-- Contains 'admin'
WHERE email LIKE '%admin%'
-- Matches: [admin@company.com](mailto:admin@company.com), [webadmin@site.org](mailto:webadmin@site.org)

下划线 (_) - 完全匹配一个字符

sql 复制代码
-- Phone pattern: XXX-XXX-XXXX
WHERE phone LIKE '___-___-____'

-- 4-letter codes starting with A
WHERE product_code LIKE 'A___'
-- Matches: A001, ABCD, A999

NOT LIKE - 排除模式:

sql 复制代码
WHERE email NOT LIKE '%@[gmail.com](http://gmail.com)'
-- Everyone except Gmail users

性能警告 ⚠️

以 % 开头的模式(LIKE '%search%')不能使用索引。它们在大型表中运行速度较慢。请谨慎使用。

快速: LIKE 'John%'(可以使用索引)

慢: LIKE '%John%'(全表扫描)


4.NULL 陷阱:为什么= NULL从不可行

最常见的 WHERE 子句错误

❌ 这是错误的,会困扰你:

sql 复制代码
SELECT * FROM employees
WHERE manager_id = NULL;
-- Returns 0 rows, even if NULLs exist!

✅ 始终使用 IS NULL:

sql 复制代码
SELECT * FROM employees
WHERE manager_id IS NULL;
-- Correctly finds rows with NULL manager_id

为什么重要

NULL 的意思是 "未知",而不是 "空"。在 SQL 的逻辑中

  • NULL = NULL返回NULL(不是 TRUE!)。
  • NULL <> NULL 返回 NULL(而不是 FALSE!)。
  • 任何与 NULL 的比较都返回 NULL

NULL 就像一个黑洞:它吞噬比较结果,却什么也不返回。

IS NULL- 检验 NULL 值:

sql 复制代码
WHERE phone IS NULL
-- Customers without phone numbers

IS NOT NULL- 检验非空值:

sql 复制代码
WHERE email IS NOT NULL
-- Users who have emails

计算中的 NULL

NULL 会 "感染 "任何计算:

sql 复制代码
-- If discount is NULL:
price - discount = NULL  (not the original price!)

解决方案:使用 COALESCE 处理 NULL:

sql 复制代码
SELECT 
    product_name,
    price,
    price - COALESCE(discount, 0) AS sale_price
FROM products;
-- COALESCE(discount, 0) means: use discount if it exists, otherwise 0

记住NULL = 未知,不为零,不为空。特别处理。


5.高级 WHERE 技术

范围查询的 BETWEEN

而不是这样:

sql 复制代码
WHERE price >= 100 AND price <= 500

使用 BETWEEN:

sql 复制代码
WHERE price BETWEEN 100 AND 500
-- Includes both 100 and 500 (inclusive)

也适用于日期:

sql 复制代码
WHERE order_date BETWEEN '2025-01-01' AND '2025-12-31'

多个值的 IN

而不是这样:

sql 复制代码
WHERE status = 'pending' 
   OR status = 'processing'
   OR status = 'shipped'

使用 IN:

sql 复制代码
WHERE status IN ('pending', 'processing', 'shipped')
-- Much cleaner!

NOT IN:

sql 复制代码
WHERE department NOT IN ('Sales', 'Marketing')
-- Everyone except these departments

EXISTS 用于子查询检查

检查相关数据是否存在:

sql 复制代码
SELECT * FROM customers c
WHERE EXISTS (
    SELECT 1 FROM orders o
    WHERE o.customer_id = c.customer_id
)
-- Customers who have placed at least one order

6.常见 WHERE 子查询错误

错误 1:使用列别名

❌ 不会起作用:

sql 复制代码
SELECT 
    price * 1.1 AS price_with_tax
FROM products
WHERE price_with_tax > 100;
-- Error: 'price_with_tax' doesn't exist

**为什么?**WHERE 在 SELECT 之前运行。别名还不存在。

✅ 重复计算:

sql 复制代码
WHERE price * 1.1 > 100

错误 2:忘记引号

WHERE 类别 = 电子产品

WHERE 类别 = "电子产品

错误 3:大小写敏感性

不同的数据库对此有不同的处理方法。请注意!

sql 复制代码
-- May or may not match 'SMITH'
WHERE last_name = 'Smith'

-- Force case-insensitive:
WHERE LOWER(last_name) = 'smith'

7.WHERE 与 HAVING:区别是什么?

WHERE在分组前过滤单行:

sql 复制代码
SELECT department, COUNT(*)
FROM employees
WHERE salary > 50000  -- Filter rows first
GROUP BY department;

HAVING在聚合后过滤分组:

sql 复制代码
SELECT department, COUNT(*)
FROM employees
GROUP BY department
HAVING COUNT(*) > 10;  -- Filter groups

经验法则:

  • 对列值使用 WHERE
  • 对聚合结果(COUNT、SUM、AVG)使用 HAVING

实践练习:测试技能

尝试为这些情况编写 WHERE 子句:

  1. 查找价格在 50 美元到 200 美元之间的产品
  2. 查找加利福尼亚州或纽约州的客户
  3. 查找 2020 年后聘用且薪资高于 60,000 美元的员工
  4. 查找名称中包含 "Pro "的产品
  5. 查找没有跟踪号码(NULL)的订单
  6. 查找技术部或市场部的活跃用户(状态 ="活跃")。

答案

sql 复制代码
-- 1
WHERE price BETWEEN 50 AND 200

-- 2
WHERE state IN ('CA', 'NY')

-- 3
WHERE hire_date > '2020-12-31' AND salary > 60000

-- 4
WHERE product_name LIKE '%Pro%'

-- 5
WHERE tracking_number IS NULL

-- 6
WHERE status = 'active' 
  AND (department = 'Tech' OR department = 'Marketing')

结论:您的 WHERE 子句核对表

现在,您已经拥有了像专家一样过滤数据的工具。在编写下一个 WHERE 子句之前,请记住

✅ 黄金法则:

  1. 对字符串使用单引号:"文本
  2. 使用 IS NULL,切勿使用 = NULL
  3. 混合 AND/OR?始终添加括号
  4. LIKE '%模式%'很慢--小心使用
  5. WHERE 在 SELECT 之前运行--不能使用别名

日常常用模式:

  • WHERE 列 = '值'- 完全匹配
  • WHERE 列 IN ('a', 'b', 'c')- 多个值
  • WHERE 列介于 x 和 y 之间--范围
  • WHERE 列 LIKE 'pattern%'- 部分匹配
  • WHERE column IS NULL- 查找缺失数据

下一步

  • 练习 20 多种不同的 WHERE 条件
  • 学习使用 JOIN 跨多个表进行筛选
  • 掌握用于复杂过滤的子查询

现在去过滤一些数据吧!🚀

相关推荐
谅望者4 小时前
每个初学者都会犯的 7 个 SQL 错误(以及如何纠正它们)
sql
不剪发的Tony老师4 小时前
Yearning:一个免费开源的SQL审核平台
数据库·sql·mysql
Gauss松鼠会4 小时前
GaussDB慢sql信息收集和执行计划查看
数据库·sql·gaussdb
呼哧呼哧.17 小时前
Spring的核心思想与注解
数据库·sql·spring
嘗_18 小时前
sql特训
数据库·sql
橙汁味的风20 小时前
3关系型数据库的SQL语言
数据库·sql
蹦跶的小羊羔1 天前
sql数据库语法
数据库·sql
PawSQL1 天前
企业级SQL审核工具PawSQL介绍(1) - 六大核心能力
数据库·sql·oracle
唐古乌梁海1 天前
【python】在Django中,执行原生SQL查询
python·sql·django