SQLite日期范围查询异常,无法筛选出全部符合条件的数据
问题原因
SQLite 没有原生的日期时间类型,所有时间值本质以字符串/数值形式存储,比较时会按照对应类型的规则判断(字符串按字典序比较)。你遇到的问题核心是比较两边的时间字符串格式不统一:
- 调用
datetime()函数时,SQLite 返回的时间字符串格式为YYYY-MM-DD HH:MM:SS(日期和时间之间是空格) - 表中存储的
date字段值绝大多数是YYYY-MM-DDTHH:MM:SS格式(日期和时间之间是字母T)
字母T的ASCII码值远高于空格,所以字典序比较时,2021-08-12T16:00:00 会被判定为大于 2021-08-12 22:00:00,只有最后两条记录符合条件:
2021-08-11T16:00:00日期前缀早于2021-08-12,自然满足小于上限的条件2021-08-12 16:00:00格式和datetime()返回值一致,时间确实早于22:00
解决方案
有三种常用修复方式,可根据场景选择:
- 方式1:查询时统一转换两边格式,适合临时快速修复
把date字段也用datetime()函数转换后再比较,保证两边格式一致:SELECT * FROM "events" WHERE datetime("date") >= datetime('2021-08-05T22:00:00') AND datetime("date") < datetime('2021-08-12T22:00:00'); - 方式2:直接用统一格式的字符串比较,性能更高
如果确定date字段都是带T的ISO8601格式,不需要调用datetime()函数,直接写字符串条件即可,ISO8601格式的字典序和时间顺序完全一致:SELECT * FROM "events" WHERE "date" >= '2021-08-05T22:00:00' AND "date" < '2021-08-12T22:00:00'; - 方式3:修复存量数据格式,避免后续再出问题
执行更新语句把所有带T的时间字符串替换为SQLite默认的空格分隔格式,后续查询就不需要额外转换:UPDATE "events" SET "date" = replace("date", 'T', ' ');
内容的提问来源于stack exchange,提问作者Boppity Bop
相关产品推荐
相关产品推荐

