【问题标题】:SQL Select between datesSQL 在日期之间选择
【发布时间】:2012-01-01 12:06:17
【问题描述】:

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

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

此语句会抓取所有日期,即使是那些超出条件的日期。您输入的日期格式与我返回的格式相同。我不确定出了什么问题。

【问题讨论】:

  • 只是一个快速的相关提示。如果您始终可以使用 yyyy/MM/dd 作为格式。它将停止可能是您的问题的讨厌的区域差异问题。

标签: sql sqlite


【解决方案1】:

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

【讨论】:

  • 更改日期格式后,我再次运行查询“SELECT date FROM test WHERE date BETWEEN "2011-11-1" AND "2011-11-2";'并获得了 2011-11-16 的结果:/
  • 那是本月的 10 号和 20 号。试试BETWEEN '2011-11-01' AND '2011-11-02'
  • @LarryLustig 你能告诉我如何解决我的问题,我的 sql server 2014 也有同样的问题
  • 如果您使用的是 Android SQLite,请确保它的 yyyy 是小写字母
  • SQLite 将日期视为字符串,无论它们采用何种格式。使用 YYYY-MM-DD 的原因是因为文本排序顺序与时间排序顺序相同。任何在较小字段之前具有较大字段的填充数字格式都可以使用。
【解决方案2】:

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

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 是的 - 但是一旦您将数据库中的格式与查询中的格式相匹配,它就会起作用。看起来它稍后被编辑以包含更新后的查询应该是什么数据库更新 - 尽管查询需要单引号而不是双引号。
【解决方案3】:

在 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' you're not going to get things from November 2011, you'll get things from many different years. The string '11-01-9999'`在他们之间也是。
【解决方案4】:

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

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

【讨论】:

  • 我认为这个解决方案的问题在于您没有指示 TEXT 的日期格式(例如,如果日期字符串存储为 'MM/DD/YYYY')。我尝试了这种方法,但它对我不起作用,我认为这就是原因。
  • 这并不像你认为的那样。在 SQLite 中,日期函数以文本形式返回日期,例如 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')) 中的格式调用它是行不通的,因为这不是它接受的格式。
【解决方案5】:
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',它应该可以工作。
  • 特别感谢Jeffvapcguy,你们的互动真的很鼓舞人心
【解决方案6】:

特别感谢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') 

【讨论】:

  • 感谢您的称赞,并且必须将它交给您,因为您有能力做子串。不过,我在另一篇文章中对julianday() 的相同评论仍然适用。这与另一个答案基本相同,除了您输入条件逻辑以添加个位数的日期和月份的前导零。可能应该已经添加到另一个答案中,或者用这个编辑替换它。赞成,因为它更正确。
【解决方案7】:

SQLite 没有日期的概念。它只知道它们是文本。当您在 SQLite 中执行此操作时,您实际上是在进行字符串比较。您可以从official documentation 了解更多信息。

当比较两个 TEXT 值时,使用适当的整理顺序来确定结果。

任何数字(即不使用“May”之类的词)格式的填充日期并按从最大字段到最小字段的顺序都可以使用。 “2021-05-07”(5 月 7 日)在“2021-05-09”(5 月 9 日)之前。因此,如果您使用“yyyy-mm-dd”格式,那么您将被设置。 “yyyy/mm/dd”和“yyyymmdd”也可以正常工作。 (有关“可排序”日期格式的更好表述,请查看RFC 3339 section 5.1。)

使用“yyyy-mm-dd”格式的原因是因为这是 SQLite 的内置 date 使用的格式。

【讨论】:

    【解决方案8】:

    将变量放在 Where 条件中并使用 'BETWEEN' 解析两个日期:

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

    ☻♥ 完成保留代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-04
      • 2012-04-17
      • 1970-01-01
      • 2013-12-27
      • 1970-01-01
      • 2011-07-04
      相关资源
      最近更新 更多