SELECT * FROM test WHERE date BETWEEN "11/1/2011" AND "11/8/2011";
这个语句获取了所有日期,即使超出了条件。你看到输入的日期格式与我得到的格式相同。我不确定问题出在哪里。
SQLite要求日期格式为YYYY-MM-DD
。由于您数据库中的数据和查询语句中的字符串不符合该格式,因此SQLite可能会将您的“日期”视为字符串。
BETWEEN '2011-11-01' AND '2011-11-02'
。 - Larry Lustig将您的数据更改为这些格式,以使用sqlite日期时间格式。
YYYY-MM-DD
YYYY-MM-DD HH:MM
YYYY-MM-DD HH:MM:SS
YYYY-MM-DD HH:MM:SS.SSS
YYYY-MM-DDTHH:MM
YYYY-MM-DDTHH:MM:SS
YYYY-MM-DDTHH:MM:SS.SSS
HH:MM
HH:MM:SS
HH:MM:SS.SSS
now
DDDDDDDDDD
SELECT * FROM test WHERE date BETWEEN '2011-01-11' AND '2011-08-11'
在SQLite中另一种选择日期的方法是使用强大的 strftime 函数:
SELECT * FROM test WHERE strftime('%Y-%m-%d', date) BETWEEN "11-01-2011" AND "11-08-2011"
根据https://sqlite.org/lang_datefunc.html,以下内容是等价的:
date(...)
strftime('%Y-%m-%d', ...)
但是如果你想要更多的选择,你可以得到它。
strftime('%Y-%m-%d','11/1/2011')
返回null,因为这不是它接受的格式。此外,如果您执行了BETWEEN '11-01-2011' AND '12-01-2011'
,您将无法获取2011年11月的内容,而是会得到许多不同年份的内容。字符串'11-01-9999'
也在其中。 - Captain ManSELECT *
FROM TableName
WHERE julianday(substr(date,7)||'-'||substr(date,4,2)||'-'||substr(date,1,2)) BETWEEN julianday('2011-01-11') AND julianday('2011-08-11')
dd/mm/yyyy
。如果你使用的是d/m/yyyy
,请在substr()
中进行更改。julianday()
函数,因为使用该函数假定您的日期是在UTC时间下,因为julianday()
函数是基于GMT时间计算的,所以如果您的日期是在本地时间下,您可能会包括一些您不想要的日期,并且漏掉一些您想要的日期。您只需执行以下查询语句即可:SELECT * FROM TableName WHERE substr(date,7)||'-'||substr(date,4,2)||'-'||substr(date,1,2) BETWEEN '2011-01-11' AND '2011-08-11'
,它应该可以正常工作。 - vapcguy或者你可以使用 date 函数将字符串转换为日期格式,即使日期在数据库中以 TEXT 存储。
像这样(最可行的变体):SELECT * FROM test WHERE date(date)
BETWEEN date('2011-01-11') AND date('2011-08-11')
2011-01-11
,因此调用 date('2011-01-11)
返回输入值。使用 SELECT * FROM test WHERE date BETWEEN '2011-01-11' and '2011-08-11';
将会产生相同的效果。但是,以 OP 中的格式调用它 (date('11/1/2011')
) 将不起作用,因为它不接受这种格式。 - Captain ManSQLite没有日期的概念,它只将其视为文本。在SQLite中进行比较时,实际上是进行字符串比较。您可以从官方文档中了解更多信息。
当比较两个TEXT值时,会使用适当的排序序列来确定结果。
任何数字(即不使用像“May”这样的单词)格式的日期,只要填充并按从最大字段到最小字段的顺序排列即可。 "2021-05-07"(5月7日)在 "2021-05-09"(5月9日)之前。因此,如果您使用“yyyy-mm-dd”格式,则可以设置。 "yyyy/mm/dd"和"yyyymmdd"也完全可以。 (有关“可排序”日期格式的更好措辞,请参见RFC 3339第5.1节。)
使用“yyyy-mm-dd”格式的原因是这是SQLite内置的date
使用的格式。
特别感谢Jeff和vapcguy,你们的互动真的很鼓舞人心。
这是一个更复杂的语句,当'/'之间的长度未知时非常有用:
SELECT * FROM tableName
WHERE julianday(
substr(substr(date, instr(date, '/')+1), instr(substr(date, instr(date, '/')+1), '/')+1)
||'-'||
case when length(
substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1),'/')-1)
)=2
then
substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1), '/')-1)
else
'0'||substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1), '/')-1)
end
||'-'||
case when length(substr(date,1, instr(date, '/')-1 )) =2
then substr(date,1, instr(date, '/')-1 )
else
'0'||substr(date,1, instr(date, '/')-1 )
end
) BETWEEN julianday('2015-03-14') AND julianday('2015-03-16')
julianday()
的评论仍然适用。这基本上与其他答案相同,只是你加入了条件逻辑来添加前导零以表示单个数字的日期和月份。可能应该将其添加到其他答案中,或者用此编辑替换其他答案。虽然如此,我还是点了赞,因为它更正确。 - vapcguy假设你正在为某个报告准备数据。那么整个过程看起来会类似于这样。
--add column with date in ISO 8601
ALTER TABLE sometable ADD COLUMN DateInISO8601;
--update the date from US date to ISO8601 date
UPDATE sometable
SET DateInISO8601 = substr([DateInUSformat],length([DateInUSformat])+1, -4)
|| '-' ||
substr('00' || [DateInUSformat],instr('00' || [DateInUSformat],'/'),-2)
|| '-' ||
substr('00' || rtrim(substr([DateInUSformat],instr([DateInUSformat],'/')+1,2),'/'),-2,2);
SELECT DateInISO8601
FROM sometable
WHERE DateInISO8601 BETWEEN '2022-02-02' AND '2022-02-22';
当然你可以在运行时完成所有操作,但如果有选择的话--不要这么做。默认使用ISO日期格式,在进出SQLite数据库时进行转换。
SELECT * FROM emp_master
-> 如果你有像dd/mm/yyyy这样简单的日期格式,那么,
WHERE joined_date BETWEEN '01/03/2021' AND '01/09/2021';
-> 如果您有日期格式,例如yyyy/mm/dd,则:
WHERE joined_date BETWEEN '2021/03/01' AND '2021/09/01';
☻♥ 完成 保留代码。