【问题标题】:How do I select dates between two given dates in an Oracle query?如何在 Oracle 查询中选择两个给定日期之间的日期?
【发布时间】:2021-08-02 19:35:07
【问题描述】:

如何在 Oracle 查询中选择两个给定日期之间的日期?

【问题讨论】:

标签: sql oracle


【解决方案1】:
SELECT TO_DATE('12/01/2003', 'MM/DD/YYYY') - 1 + rownum AS d
FROM all_objects
WHERE TO_DATE('12/01/2003', 'MM/DD/YYYY') - 1 + rownum <= TO_DATE('12/05/2003', 'MM/DD/YYYY')

来自

http://forums.devshed.com/oracle-development-96/select-all-dates-between-two-dates-92997.html

【讨论】:

  • -1 此代码示例(来自链接页面)正在回答一个略有不同的问题,并且比此处提出的问题所需要的更复杂。
  • @payne,到目前为止,Greg 给出了最好的答案。所有其他人假设涉及到一个表。诚然,这可能是 OP 想要(而不是 did)所要求的,但话又说回来,如果有人懒得说出他想要什么,他应该得到什么他问。因此+1
  • 我猜由于要求有点模糊,所以不清楚 OP 是否想从表格中进行选择 - 我想我们会找出答案是否被接受以及何时被接受。
  • 基于表格的任何内容都基于您的日期范围将小于表格中的行数的概念。如果您碰巧在一个很大的日期范围内传递此解决方案将失败。这就是为什么像我的解决方案一样使用 LEVEL 伪列更可取,因为它适用于任何任意范围。
  • 假设如果我需要将 startdate 作为 sysdate(current date) 而不是特定日期,我该怎么办?
【解决方案2】:
SELECT * FROM your_table WHERE your_date_field BETWEEN DATE '2010-01-01' AND DATE '2011-01-01';

【讨论】:

  • 谁说过关于 2010 年 1 月 1 日至 2011 年 1 月 1 日的任何事情,我不妨问问。有什么区别??? sysdate 是 2010 年 1 月 1 日的日期
  • 好吧,因为 sysdate 与通常的日期略有不同,并且没有解释 sysdate 的作用 - 坚持使用传统日期会更有意义。 SysDate 没有问题 - 但它需要您提供的更多解释。
  • @Ronnis - 而不是仅仅投反对票,您如何回答问题并提供替代方案?
  • @Andy Paton,如果您使用 to_Date 或 DATE 文字,我宁愿支持您的。
  • 好吧,你们两个,别吵了,否则我会把你们的玩具拿走……然后给你们两个投反对票。
【解决方案3】:

您可以以一种巧妙的方式使用 LEVEL 伪列来生成一个系列,因此,例如,要获取从今天到 20 天之间的天数列表,我可以:

select trunc(sysdate+lvl) from
  (select level lvl from dual connect by level < ((sysdate+20)-sysdate - 1) )
order by 1  

一般来说,您可以看到这将如何适用于任何两个给定日期。

select trunc(early_date+lvl) from
  (select level lvl from dual connect by level < (later_Date-early_date-1) )
order by 1 

如果您还想包括两个结束日期,您可以调整条款。

【讨论】:

    【解决方案4】:

    您还可以使用以下内容获取日期范围之间的日历日期列表(类似于 Michael Broughton 的解决方案)

    select (trunc(sysdate) - (trunc(sysdate) - (to_date('start_date')))) -1 + level  from dual
    connect by level <= 
    ((select (trunc(sysdate) - (trunc(sysdate) - (to_date('end_date'))))-
    (trunc(sysdate) - (trunc(sysdate) - (to_date('start_date'))))from dual)+1);
    

    【讨论】:

      【解决方案5】:

      我经常为我工作的调度应用程序这样做,我创建了一个流水线表函数。有时我需要几天、几小时或 15 分钟的间隔。这不完全是我的功能,因为我的代码在一个包中。例如,在这里,我得到了 2020 年 1 月 1 日到 2020 年 1 月 10 日之间的天数:

      SELECT
          days.date_time
      FROM
          table(between_times(TO_DATE('2020-01-01'),TO_DATE('2020-01-10'),(60*24), 'Y')) days
      

      流水线函数:

      function between_times(i_start_time TIMESTAMP, i_end_time TIMESTAMP, i_interval_in_minutes NUMBER, include_end_time VARCHAR2 := 'N')
        RETURN DateTableType  PIPELINED
        AS
          time_counter TIMESTAMP := i_start_time;
        BEGIN
          IF i_start_time IS NULL OR i_end_time IS NULL or i_start_time > i_end_time OR i_interval_in_minutes IS NULL OR
            i_interval_in_minutes <= 0 THEN
              RETURN;
            END IF;
            LOOP
      
              -- by default does not include end time
              if (include_end_time = 'Y') THEN
                exit when time_counter > i_end_time;
              ELSE
                exit when time_counter >= i_end_time;
              END IF;
              
              
              pipe row(DateType( time_counter ));     
              time_counter := time_counter + i_interval_in_minutes/(60*24);
              
            END LOOP;
            
            EXCEPTION  WHEN NO_DATA_NEEDED THEN NULL;      
        END;
      

      【讨论】:

        【解决方案6】:

        使用“之间”。一般意义上的:

        select * from someTable where dateCol between date1 and date2;
        

        请注意,dateCol 被定义为日期,并且 date1 和 date2 也是日期值。如果这些不是日期,那么您将使用 to_date 函数将它们转换为日期。

        【讨论】:

          【解决方案7】:

          with all_days as (select trunc(to_date('12-03-2017','dd-mm-yyyy')+levl)-1 as all_dates from (从双连接中选择级别级别

          【讨论】:

          • 此查询不会生成日期列表。
          猜你喜欢
          • 1970-01-01
          • 2011-07-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-07
          • 1970-01-01
          • 2015-04-01
          • 1970-01-01
          相关资源
          最近更新 更多