月末日期范围,其中最近一天 = 系统日期

Posted

技术标签:

【中文标题】月末日期范围,其中最近一天 = 系统日期【英文标题】:Month End Date Range where most recent day = system date 【发布时间】:2020-02-18 13:23:41 【问题描述】:

我正在尝试生成从给定开始日期 (01/01/2019) 到系统日期 (sysdate) 的“本月最后一天”日期范围。 我可以使用以下查询为此生成日期范围:

select last_day(add_months (trunc (to_date('01/01/2019','MM/DD/YYYY'), 'MM'), Level - 1))

Month   FROM Dual

CONNECT BY Level <= MONTHS_BETWEEN(sysdate, to_date('01/01/2019','MM/DD/YYYY')) + 1

order by month

我试图让最后一条记录与 sysdate 相等,以便计算运行余额 - 如何将其添加到上述查询中?

解决方案的示例输出:

+------------------------+
|         MONTH          |
+------------------------+
| 1/31/2019 12:00:00 AM  |
| 2/28/2019 12:00:00 AM  |
| 3/31/2019 12:00:00 AM  |
| 4/30/2019 12:00:00 AM  |
| 5/31/2019 12:00:00 AM  |
| 6/30/2019 12:00:00 AM  |
| 7/31/2019 12:00:00 AM  |
| 8/31/2019 12:00:00 AM  |
| 9/30/2019 12:00:00 AM  |
| 10/31/2019 12:00:00 AM |
| 11/30/2019 12:00:00 AM |
| 12/31/2019 12:00:00 AM |
| 1/31/2020 12:00:00 AM  |
| 2/25/2020 12:00:00 AM  |
+------------------------+

【问题讨论】:

【参考方案1】:

如果我理解正确,您会希望今天的日期位于最后一行。如果是这样,请使用 CASE(第 13 - 19 行)。

第 1 - 12 行代表您当前的查询。

SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';

Session altered.

SQL> WITH your_data
  2       AS (    SELECT LAST_DAY (
  3                         ADD_MONTHS (
  4                            TRUNC (TO_DATE ('01/01/2019', 'MM/DD/YYYY'), 'MM'),
  5                            LEVEL - 1))
  6                         Month
  7                 FROM DUAL
  8           CONNECT BY LEVEL <=
  9                           MONTHS_BETWEEN (
 10                              SYSDATE,
 11                              TO_DATE ('01/01/2019', 'MM/DD/YYYY'))
 12                         + 1)
 13    SELECT CASE
 14              WHEN TRUNC (month, 'mm') = TRUNC (SYSDATE, 'mm')
 15              THEN
 16                 TRUNC (SYSDATE)
 17              ELSE
 18                 month
 19           END
 20              month
 21      FROM your_data
 22  ORDER BY month;

MONTH
-------------------
31.01.2019 00:00:00
28.02.2019 00:00:00
31.03.2019 00:00:00
30.04.2019 00:00:00
31.05.2019 00:00:00
30.06.2019 00:00:00
31.07.2019 00:00:00
31.08.2019 00:00:00
30.09.2019 00:00:00
31.10.2019 00:00:00
30.11.2019 00:00:00
31.12.2019 00:00:00
31.01.2020 00:00:00
18.02.2020 00:00:00

14 rows selected.

SQL>

【讨论】:

【参考方案2】:

当我第一次看到这个时,我立即认为递归 CTE 会是完美的。我不断遇到无法解决的递归类型不匹配的问题。事实证明,Oracle 11g 在递归 CTE 中存在一个带有日期递归的错误。这终于让我终于更新了。所以谢谢你的问题。无论如何,对于未来的观众来说,递归 CTE 确实有效。

alter session set nls_date_format = 'yyyy-mm-dd';
with date_list (dte) as
   ( select last_day(date '2019-01-01') from dual   
     union all 
     select least(add_months(dte,1), trunc(sysdate))  
       from date_list
      where dte<trunc(sysdate)
   )  
select dte from date_list;  

【讨论】:

以上是关于月末日期范围,其中最近一天 = 系统日期的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Angular 日期范围选择器中的日期设置为该月的第一天

从日期范围创建日期和小时列

Oracle获取一段时间范围内的日期,从2006-01-01到2013-12-31的每一天的日期表

角度日期范围选择器 - 如何在已经使用 min 属性将最小日期设置为今天时禁用同一天

我可以将范围内的日期限制为最少一天吗?

SQL语句:取某个日期所在季度的最后一天,精确到时分秒