SQL WHERE 子句:数据筛选的核心逻辑与实战指南
一、引言:为什么 WHERE 如此重要?
在 SQL 中,WHERE
子句是数据筛选的 “过滤器”,类比 Python 中的if
语句,决定哪些行能进入结果集。掌握它,就能从海量数据中精准提取所需信息,是数据分析和开发的必备技能。
二、WHERE 基本用法:从简单筛选到运算符对比
1. 基础语法:筛选单价 > 500 的商品
sql
SELECT sku_name, sku_price
FROM commodity
WHERE sku_price > 500;
- 逻辑:仅返回
sku_price
大于 500 的行,类似 Python 的if sku_price > 500
。
2. 运算符对比(SQL vs Python)
功能 | Python | SQL |
---|---|---|
等于 | == | = |
不等于 | != | <> (或!= ,部分数据库支持) |
大于 / 小于 | > , < | 同 Python |
示例:SQL 中WHERE age = 18
表示 “年龄等于 18”,而 Python 中需写age == 18
。
三、特殊场景处理:时间与缺失值
1. 时间数据筛选:精确到秒的 “隐形规则”
sql
-- 筛选1994-08-30之后出生的人(含当天零点整)
SELECT * FROM users
WHERE birth > '1994-08-30';
- 注意:
- 时间需用引号包裹(如
'YYYY-MM-DD'
)。 - SQL 默认时间为
'YYYY-MM-DD 00:00:00'
,即 “当天零点”,若需包含全天,可写birth >= '1994-08-30'
。
- 时间需用引号包裹(如
2. 缺失值(NULL):不是 “0”,而是 “无数据”
NULL
vs0
:0
是有效数据(如订单金额 0 元,代表免费)。NULL
是缺失值(如订单金额 NULL,代表数据未录入或异常)。
- 查询 NULL:
sql
-- 提取联系表中无电话号码的记录 SELECT * FROM contact_info WHERE phone_number IS NULL;
四、SQL 子句执行顺序:为什么WHERE
不能用SELECT
别名?
执行顺序(从先到后):
FROM
→ WHERE
→ SELECT
→ ORDER BY
→ LIMIT
- 关键限制:
WHERE
在SELECT
之前执行,因此 **WHERE
子句中无法使用SELECT
定义的别名 **(如discount
)。
例:sql
-- 错误!WHERE先执行,此时discount尚未定义 SELECT discount_price/price AS discount FROM commodity WHERE discount <> 1; -- 报错:discount列不存在
正确写法需重复计算(如WHERE discount_price/price <> 1
),或使用子查询(进阶技巧)。
五、实战练习题:提取折扣最大的前 3 商品
题目:
从commodity
表中,筛选折扣(discount_price/price ≠ 1
)的商品,按折扣比例(升序,即折扣最大)取前 3 名,输出name
和discount
。
代码解析:
sql
SELECT name, discount_price/price AS discount
FROM commodity
WHERE discount_price/price <> 1 -- 筛选有折扣(≠1)
ORDER BY discount_price/price -- 按折扣比例升序(越小折扣越大)
LIMIT 3; -- 取前3条
- 为什么
WHERE
和ORDER BY
用原始表达式?
因执行顺序:WHERE
和ORDER BY
在SELECT
之前,此时discount
别名尚未生成,必须重复计算discount_price/price
。
六、总结:掌握 WHERE,掌控数据筛选
- 核心能力:筛选(
WHERE
)、排序(ORDER BY
)、限制(LIMIT
)的组合使用。 - 避坑指南:
- 时间数据加引号,区分
NULL
与0
。 - 牢记子句执行顺序,避免
WHERE
中使用SELECT
别名。
- 时间数据加引号,区分
- 实战价值:从电商折扣分析到用户画像筛选,
WHERE
是数据清洗和分析的第一步。