where拼接多条件需注意运算符优先级、null处理及索引生效;and/or组合须加括号防歧义,not对null无效需显式补is null;in/between可优化等值或范围查询;索引命中需满足最左前缀原则,用explain query plan验证;where不可用select别名或聚合结果,排序字段不自动建索引。

直接用 WHERE 拼接多个条件即可,但必须注意运算符优先级、NULL 处理和索引是否生效。
AND / OR 逻辑组合的写法与陷阱
SQLite 支持标准 SQL 的 AND、OR、NOT,但不支持短路求值(即所有子条件都会被计算),所以 OR 里带函数或子查询时性能容易失控。
- 多条件且关系明确时,优先用
AND:例如SELECT * FROM users WHERE status = 'active' AND age >= 18 AND created_at > '2024-01-01' - 用
OR时务必加括号,避免被默认优先级干扰:WHERE (type = 'admin' OR type = 'moderator') AND active = 1,而不是WHERE type = 'admin' OR type = 'moderator' AND active = 1(后者等价于type = 'admin' OR (type = 'moderator' AND active = 1)) -
NOT对NULL无效:NOT age > 30不会命中age IS NULL的行,得显式补上:NOT (age > 30) OR age IS NULL
IN 和 BETWEEN 替代重复的 = 或 >= +
IN 和 BETWEEN 是语法糖,但影响可读性、执行计划和索引使用效率。它们不是万能的,尤其在参数动态拼接时容易出错。
-
IN等价于多个OR,但 SQLite 对IN的常量列表有优化(比如转成哈希查找),而手写的OR链可能触发全表扫描 -
BETWEEN是闭区间,age BETWEEN 18 AND 65包含 18 和 65;若要开区间,得写成age > 18 AND age - 混合使用时注意括号层级:
WHERE (score BETWEEN 60 AND 100) AND category NOT IN ('temp', 'draft'),否则AND可能被误绑定到NOT IN左侧
多条件查询能否走索引?关键看最左前缀
SQLite 的 B-tree 索引只对满足「最左前缀原则」的条件生效。建了复合索引 CREATE INDEX idx_user_status_age ON users(status, age),以下查询才能高效利用它:
-
WHERE status = 'active'✅(只用第一列) -
WHERE status = 'active' AND age > 25✅(前缀完整 + 范围) -
WHERE age > 25❌(跳过第一列,索引失效) -
WHERE status IN ('active', 'pending') AND age = 30✅(IN视为等值,仍符合前缀)
用 EXPLAIN QUERY PLAN SELECT ... 查看是否出现 SEARCH TABLE 而非 SCAN TABLE,这是判断索引是否命中的最快方式。
WHERE 中不能用 SELECT 别名,也不能依赖计算列顺序
WHERE 子句在 SQL 执行顺序中早于 SELECT,所以你在 SELECT 里定义的别名(如 SELECT price * 1.1 AS final_price)在 WHERE 里不可见。
- 错误写法:
SELECT price * 1.1 AS final_price FROM products WHERE final_price > 100→ 报错no such column: final_price - 正确写法:重复表达式
WHERE price * 1.1 > 100,或改用子查询/CTE - 同样,
WHERE无法引用GROUP BY或HAVING中的聚合结果,这类过滤必须挪到HAVING
真正容易被忽略的是:哪怕你写了 SELECT a, b, c FROM t WHERE b > 10 ORDER BY a,SQLite 也**不会**因为 ORDER BY a 就自动给 a 加索引——排序字段本身不触发索引创建,得手动建。










