SQLite中VARCHAR类型日期列的区间数据提取问题咨询
解决SQLite中VARCHAR日期列的范围查询问题
嘿,我来帮你搞定这个日期查询的麻烦事儿!你的核心问题在于:Date列存的是DD/MM/YYYY HH:MM:SS格式的字符串,而SQLite直接按字符串比较或者用strftime处理时,因为格式不匹配,根本没法正确识别日期的先后顺序,所以之前的查询结果才会不对。
为啥之前的查询没效果?
- 直接用
BETWEEN比字符串:比如'14/03/2017'和'16/03/2018',字符串是按字符逐个比的,像'01/04/2017'会被认为比'31/03/2017'小,但实际日期明明是后者更早,结果自然错得离谱。 - 用
strftime('%d/%m/%y %H:%M:%S', Date):strftime的第二个参数得是SQLite能认的日期格式(比如YYYY-MM-DD HH:MM:SS),但你的Date列是日/月/年的格式,strftime根本解析不了,转换出来的值全乱了,比较当然也没用。
正确的查询姿势
我们得把DD/MM/YYYY HH:MM:SS格式的字符串转成SQLite能识别的YYYY-MM-DD HH:MM:SS格式,再做范围比较。用substr拆分重组就行:
SELECT * FROM Table1 WHERE -- 把Date列的日/月/年转成年-月-日格式,保留时分秒 substr(Date, 7, 4) || '-' || substr(Date, 4, 2) || '-' || substr(Date, 1, 2) || ' ' || substr(Date, 12) BETWEEN '2017-03-14 17:00:10' AND '2018-03-16 17:00:12';
嫌麻烦的话,也可以用datetime函数配合字符串替换来简化:
SELECT * FROM Table1 WHERE datetime( replace(substr(Date, 1, 10), '/', '-'), substr(Date, 12) ) BETWEEN '2017-03-14 17:00:10' AND '2018-03-16 17:00:12';
长远建议
如果能改表结构的话,强烈建议把Date列改成TEXT类型,并且存储ISO标准的日期格式(YYYY-MM-DD HH:MM:SS),这样以后查日期会简单太多,还能避免各种格式解析的坑。给你个修改示例:
-- 先加一个新的ISO格式日期列 ALTER TABLE Table1 ADD COLUMN iso_date TEXT; -- 把旧日期转成ISO格式存进去 UPDATE Table1 SET iso_date = substr(Date, 7, 4) || '-' || substr(Date, 4, 2) || '-' || substr(Date, 1, 2) || ' ' || substr(Date, 12); -- 要是旧列没用了,可以删掉(可选) ALTER TABLE Table1 DROP COLUMN Date;
之后查询就超简单了:
SELECT * FROM Table1 WHERE iso_date BETWEEN '2017-03-14 17:00:10' AND '2018-03-16 17:00:12';
内容的提问来源于stack exchange,提问作者Andrzej Koloszewski




