SQL在日期之间选择


69

我正在运行sqlite以选择两个范围之间的数据作为销售报告。要从两个日期之间选择数据,我使用以下语句:

SELECT * FROM test WHERE date BETWEEN "11/1/2011" AND "11/8/2011";

该语句将获取所有日期,甚至超出条件的日期。您输入的日期格式与我输入的日期格式相同。我不确定发生了什么问题,但感谢您能找到的任何帮助。谢谢!


2
只是一个快速的相关技巧。如果您始终可以使用yyyy / MM / dd作为格式。这将阻止可能是您的问题的令人讨厌的区域差异问题。
哈德良

Answers:


95

SQLLite要求日期采用YYYY-MM-DD格式。由于数据库中的数据和查询中的字符串不是这种格式,因此可能会将“日期”视为字符串。


1
更改日期格式后,我再次以“选择测试日期从“ 2011-11-1”和“ 2011-11-2”之间的测试日期开始”查询;并获得了2011-11-16的结果:/
Zombian 2011年

33
那是每月的10号和20号。尝试BETWEEN '2011-11-01' AND '2011-11-02'
拉里·路斯蒂格

@LarryLustig您能告诉我如何解决我的问题,我对sql server 2014有同样的问题
r.hamd 2015年

1
如果您使用的是Android SQLite,请确保以小写字母表示yyyy
Ajji 2016年

35

将数据更改为该格式以使用sqlite datetime格式

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'

正确的主意,但考虑到返回的数据也是MM/DD/YYYY格式,我怀疑这仍然行不通,因为他数据库中的数据将被视为字符串而非日期。
埃里克·彼得罗里耶

@EricPetroelje是的-但是一旦您将数据库中的格式与查询中的格式匹配,就可以使用。看起来它稍后进行了编辑,以包含数据库更新后更新后的查询应该是什么-尽管查询需要单引号而不是双引号。
vapcguy '16

14

在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', ...)

但是如果您想要更多选择,就可以选择。


引号应为单引号,否则查询应可用。
vapcguy

4

或者,您可以使用date函数将字符串转换为Date格式。甚至日期也以TEXT的形式存储在数据库中。像这样(最可行的变体):

SELECT * FROM test WHERE date(date) 
BETWEEN date('2011-01-11') AND date('2011-8-11')

我认为此解决方案的问题是您未指示TEXT的日期格式(例如,如果日期字符串存储为“ MM / DD / YYYY”)。我尝试了这种方法,但它对我不起作用,我认为这就是原因。
泽西豆

4
SELECT *
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

特别感谢Jeffvapcguy,您的互动确实令人鼓舞
TROUZINE Abderrezaq

1

特别感谢Jeffvapcguy,您的互动确实令人鼓舞。

这是一个更复杂的语句,当'/'之间的长度未知时非常有用:

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') 

1
感谢您的赞美,并请您将其交给您来做子字符串。我julianday()对其他帖子的相同评论仍然适用。这与其他答案基本相同,不同之处在于您输入了条件逻辑以在前几位数的天和月中添加前导零。可能应该已经添加到其他答案中,或用此编辑替换了它。赞成,因为它更正确。
vapcguy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.