You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动