SQLite聚合子查询无法引用外层SELECT 如何计算逐行后续最小值
原有SQL问题说明
你写的SQL存在两处问题导致无法正常运行:
- 子查询中缺失
WHERE关键字,直接使用AND拼接过滤条件,本身存在语法错误 - 包括SQLite在内的绝大多数SQL引擎执行顺序中,
SELECT子句的别名生成晚于WHERE子句的过滤执行,因此内层子查询无法直接引用外层SELECT中定义的thistime别名。另外如果TimeValue是唯一时间值,你原有语句中的GROUP BY是多余逻辑,不需要添加。
正确实现方式
方法1:兼容所有SQLite版本的关联子查询写法
给内外层查询的表分别设置别名,直接通过表名.字段名的方式做关联,不需要引用外层SELECT的别名:
SELECT t1.TimeValue, ( SELECT MIN(t2.Low) FROM MyTable t2 WHERE t2.TimeValue >= t1.TimeValue ) AS `Min(Low)` FROM MyTable t1 ORDER BY t1.TimeValue;
方法2:SQLite 3.25+ 支持的窗口函数写法(性能更优)
如果你的SQLite版本在3.25及以上(支持窗口函数特性),推荐用窗口函数实现,避免逐行执行子查询的性能损耗,数据量越大优势越明显:
SELECT TimeValue, MIN(Low) OVER ( ORDER BY TimeValue DESC ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) AS `Min(Low)` FROM MyTable ORDER BY TimeValue;
注意:如果你的
Low字段是存储为带前导零的字符串类型,需要将MIN(Low)替换为MIN(CAST(Low AS INTEGER)),否则会按字符串字典序取最小值,和数值排序的结果不一致。
两种写法执行后都会返回你预期的结果:
| TimeValue | Min(Low) |
|---|---|
| 14:00 | 012 |
| 14:30 | 012 |
| 15:00 | 145 |
| 15:30 | 145 |
| 16:00 | 678 |
内容的提问来源于stack exchange,提问作者Ian S
相关产品推荐
相关产品推荐

