嵌套查询适合轻量预警,但受单值约束、NULL逻辑和性能限制;WHERE中子查询须返回单值,否则报错。

嵌套查询能直接在查询时完成阈值比对,但容易因单值约束、NULL 逻辑或性能问题失效——它适合轻量预警,不适合高频或大数据场景。
WHERE 子句里的子查询必须返回单值
常见错误是 SELECT * FROM inventory WHERE stock_qty 报错 <code>Subquery returns more than 1 row。这说明 thresholds 表里没加限制条件,返回了多行。
- 如果阈值按商品配置,子查询必须带
WHERE product_id = i.product_id,且product_id在thresholds表上有唯一索引 - 如果阈值是全局统一值(比如所有商品警戒线都是 5),直接写
stock_qty ,别硬套子查询 - 若子查询结果为
NULL(例如某商品没配阈值),整个表达式判为UNKNOWN,该行不会被查出——这不是 bug,是 SQL 三值逻辑的正常表现
用 LEFT JOIN 替代相关子查询提升性能
当 inventory 表超过万级数据,WHERE 中每行都执行一次子查询会导致 DEPENDENT SUBQUERY,执行变慢 3–10 倍。
- 改用
LEFT JOIN thresholds t ON i.product_id = t.product_id,让优化器一次性走索引联结 - 务必给
thresholds.product_id加索引,否则 JOIN 退化为全表扫描 - 用
COALESCE(t.alert_value, 10)处理缺失阈值,避免用0导致所有无配置商品都被误报 - SQLite 不支持在
WHERE中用COALESCE推导索引,此时建议先SELECT product_id FROM thresholds拿到有阈值的商品集,再查库存
多维度阈值匹配时别硬关联 product_id
现实中预警值常按品类、仓库或供应商配置,不是每个商品都有独立记录。强行用 product_id 关联会漏数据或错配。
- 先确认业务规则:预警到底归属哪个维度?比如按品类,则关联路径是
inventory → categories → thresholds - 典型写法:
JOIN categories c ON i.category_id = c.id JOIN thresholds t ON c.category_code = t.scope_value WHERE t.scope_type = 'category' - 字段名如
scope_type、scope_value是通用设计,具体以你库中实际字段为准 - 若一个商品匹配多个阈值(如同时命中品类和供应商规则),需约定优先级,可用
ROW_NUMBER() OVER (PARTITION BY i.product_id ORDER BY priority DESC)取最高优的一条
嵌套查询看着简洁,但真正上线时最容易栽在“阈值来源不唯一”和“NULL 语义被忽略”这两点上——查不出数据时,先看子查询是否真只返回一行,再看有没有 NULL 干扰判断逻辑。

















