数据库入门到初级 · 第 08/22 篇。实验口径:MySQL 8.4、InnoDB、utf8mb4。案例:小型商城。
“给我看看 50 到 200 元、有货且在售的商品。”这是一句很自然的话。写 SQL 的任务,就是把其中每个条件明确表达出来。条件越清楚,越容易发现边界和遗漏。
1. 比较条件与 AND
SELECT id, name, price, stock
FROM products
WHERE price >= 50
AND price <= 200
AND stock > 0
AND is_on_sale = 1
ORDER BY id;
样例结果为机械键盘、无线鼠标、笔记本支架。AND 要求各条件同时成立。常见比较符有 =、<>、>、>=、<、<=;SQL 中等于写一个 =,不是许多编程语言里的 ==。

WHERE 中只保留判断为真的行。遇到 NULL 时,比较可能得到“未知”,并不会自动当作符合条件。
2. OR 和括号:别让下架商品溜进来
需求是“在售,并且便宜或者库存较多”。正确写法:
SELECT id, name
FROM products
WHERE is_on_sale = 1
AND (price < 100 OR stock >= 20)
ORDER BY id;
AND 的优先级高于 OR。如果写成 is_on_sale = 1 AND price < 100 OR stock >= 20,含义就变为“在售且便宜,或者库存较多”。最后一个分支没有在售限制。
即使原始样例暂时没有让错误暴露的商品,这段条件依然可能是错的。检查逻辑不能只靠“今天查出来看着差不多”;可以构造一个下架且库存 50 的商品来推演边界。
3. IN 和 BETWEEN:表达范围与集合
SELECT id, status FROM orders
WHERE status IN ('paid', 'pending')
ORDER BY id;
SELECT id, name FROM products
WHERE price BETWEEN 89.00 AND 199.00
ORDER BY id;
IN 适合有限的候选值。BETWEEN 包含两端,所以 89 元和 199 元都被选中。时间区间则常用 >= 起点 AND < 下一段起点,减少日期边界歧义。
4. LIKE:从简单关键词搜索开始
SELECT id, name FROM products
WHERE name LIKE '%鼠标%';
% 匹配零个或多个字符,_ 匹配一个字符。这个例子找名称中含“鼠标”的商品。大小写和某些字符比较行为受排序规则影响。
如果用户真的想搜百分号或下划线,需要正确转义通配符,不能直接把原始输入当作匹配模式。应用还应使用参数化查询;“参数化”防止 SQL 结构被注入,“转义通配符”控制搜索语义,它们解决不同问题。
前导 % 的搜索通常难以直接利用普通 B-tree 索引定位字符串前缀。入门时先写对,后续根据搜索规模选择索引或搜索方案,不要承诺所有模糊搜索都能靠加普通索引变快。
5. NULL 必须单独判断
SELECT name FROM users WHERE phone IS NULL;
SELECT name FROM users WHERE phone IS NOT NULL AND phone <> '';
分别得到小周与小林。phone = NULL 不会得到想要的“未填写手机号”结果。业务若把空字符串也当作未填写,可以明确写 phone IS NULL OR phone = '',以后再统一清理存储规则。
6. 日期筛选采用清楚的边界
SELECT id, created_at FROM orders
WHERE created_at >= '2026-01-10 00:00:00'
AND created_at < '2026-01-12 00:00:00'
ORDER BY id;
应得到 1001、1002 两张订单。不要用 < '2026-01-11 00:00:00' 表示“包含 11 日全天”,也不要在业务没有统一时区时混用本地日期与 UTC 日期。
练习与答案
练习:找出仍在售但已经缺货的商品。
SELECT id, name FROM products
WHERE is_on_sale = 1 AND stock = 0;
结果为数据线。再想一步:“库存不足”和“已下架”是不是同一个状态?不是,所以样例用两个字段分别表达它们。
上一篇:第 07 篇 · 系列目录 · 下一篇:第 09 篇