【问题标题】:How to get records between from and to date, when dates are for the same month/year?当日期为同一月/年时,如何获取从和到日期之间的记录?
【发布时间】:2016-05-28 01:55:59
【问题描述】:

我正在尝试创建一个查询,该查询可以在表中获取一些记录,该表介于从开始到截止日期之间,日期仅为月/年。我遇到的问题是尝试在起始日期和结束日期为同一月/年时获取记录。

这是我遇到的问题的一个示例:

select start_date 
from job
where trunc(start_date) between to_date('05-2016','mm-yyyy') and to_date('05-2016','mm-yyyy')

在作业表中,有 start_date 在 5 月份的记录,但为了查看它们,我需要将截止日期设置为“06-2016”。有没有办法通过指定开始日期和结束日期是 05-2016 来获取 5 月份的所有 start_date 记录?

【问题讨论】:

  • 您使用的是哪个 DBMS?
  • 您没有指定日期是有原因的吗? between to_date('05-01-2016', 'mm-dd-yyyy') and to_date('05-31-2016', 'mm-dd-yyyy') 是因为您不知道如何计算月份的最后一天,还是因为该日期仅提供给您月份和年份?
  • 请注明Oracle Sql,最好是你使用的版本(即10g)
  • 您的代码应该可以工作。一个问题是start_date 上的时区问题。换句话说,您的问题没有足够的信息来回答。
  • 我认为这是对 between 函数中的日期的误解。在这种情况下,它们都是 5/1。这只会选择 5/1 的 start_dates

标签: sql


【解决方案1】:

在您的示例中,您选择了 2016 年 5 月 1 日到 2016 年 5 月 1 日之间的所有 start_date

您似乎想在一个月内捕获所有内容,但您没有指定要截断的格式。如果没有在 Trunc() 中指定“月份”,您将截断到当天。当您现在可以截断到 Month 时,实际上只需将其设置为等于 to_date() 而不是介于:

select start_date 
from job
where trunc(start_date,'Month') = to_date('05-2016','mm-yyyy')

Here is some information 在 Trunc(日期,[fmt])上。当 fmt 参数留空时,Trunc() 默认为“舍入”到最近的一天,但还有许多其他选项。

如果您想指定大于一个月的范围,您可以在之间使用(但请注意,这是从第一个 to_date() 的第一天到第二个 'to_date()' 的第一天:

select start_date 
from job
where trunc(start_date) 
between to_date('06-2016','mm-yyyy') 
and to_date('09-2016','mm-yyyy')

在此示例中,所有 Start_dates 都将在 2016 年 6 月 1 日到 2016 年 9 月 1 日之间填充。

我认为最准确的方法是:

select start_date 
from job
where trunc(start_date) 
between to_date('06-01-2016','mm-dd-yyyy') 
and to_date('09-30-2016','mm-dd-yyyy')

【讨论】:

    【解决方案2】:

    怎么样?

    select start_date 
    from job
    where trunc(start_date, 'mm') between
            to_date('05-2016', 'mm-yyyy')
        and to_date('05-2016', 'mm-yyyy')
    

    Oracle 无法将 between 右端的日期插入到月底。当to_date() 缺少格式中的日期值时,它只提供第一个作为默认值。不确定这是否是您预期的行为。

    如果您改为按月(而不是按天)截断日期,则比较将仅涉及落在该月第一天的日期。随着日期以这种方式折叠,您可以将两个相同值的开始和结束视为一个包含范围。大概你会用某种形式的参数替换硬编码的日期,这也适用于更广泛的范围。当然,如果您总是在一个月内查询,between 可以只是一个相等性测试。而且这不会在您的列上使用索引,因此它不一定是最有效的。

    我认为这就是您要寻找的。您是否有理由需要以该格式提供日期值?也许有一个更好的方法可以使用一点日期数学来解决这个问题。

    【讨论】:

      【解决方案3】:

      试试这样:

      select start_date 
      from job
      where trunc(start_date) between to_date('05-2016','mm-yyyy')
      and dateadd('d', -1, dateadd('m', 1, to_date('05-2016','mm-yyyy')))
      

      要查看整个月的日期,between 子句中的日期范围必须是整月。

      【讨论】:

      • 这个想法是合理的。但是between 将包含一个太多的月份。您需要严格小于。
      • @shawnt00,我已经编辑了我的答案来解决这个问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-13
      • 2012-07-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多