首页 > 解决方案 > 如何根据 sysdate 获取过去一年的不同日期范围

问题描述

我有一个场景:根据我的 sysdate,我需要捕获过去 12 个月的日期。

示例:我将得到一个数字参数,例如:2,3,4,6 ..

如果参数是 3: 那么根据 sysdate-12 我期待 4 条记录如下

Start_Date  End_Date
20180801    20181101
20181101    20190201
20190201    20190501
20190501    20190827

select TO_CHAR(add_months(trunc(sysdate, 'month'), -12),'YYYYMMDD') Start_Date,TO_CHAR(add_months(trunc(sysdate, 'month'), -9),'YYYYMMDD') End_Date from dual 
union all 
select TO_CHAR(add_months(trunc(sysdate, 'month'), -9),'YYYYMMDD') Start_Date,TO_CHAR(add_months(trunc(sysdate, 'month'), -6),'YYYYMMDD') End_Date from dual 
union all 
select TO_CHAR(add_months(trunc(sysdate, 'month'), -6),'YYYYMMDD') Start_Date,TO_CHAR(add_months(trunc(sysdate, 'month'), -3),'YYYYMMDD') End_Date from dual 
union all 
select TO_CHAR(add_months(trunc(sysdate, 'month'), -3),'YYYYMMDD') Start_Date,TO_CHAR(trunc(sysdate),'YYYYMMDD') End_Date from dual

在两个日期之间,我相差了 3 个月。如果参数为 2,那么 Start_Date 和 End_Date 之间的差异应该是 2 个月,这意味着我将获得 6 条记录。

我们可以编写一个查询来读取这个数字参数并在参数的基础上创建记录。如果没有像上面那样编写多个查询,有没有可能我可以读取参数并创建记录

标签: sqloracle

解决方案


您可以使用以下查询:

SELECT
    ADD_MONTHS(START_,(LEVEL - 1) * &&INPUT_NUMBER) AS START_DATE,
    CASE
        WHEN LEVEL = 12 / ( &&INPUT_NUMBER ) THEN SYSDATE
        ELSE ADD_MONTHS(START_,(LEVEL) * &&INPUT_NUMBER)
    END AS END_DATE
FROM
    (
        SELECT
            ADD_MONTHS(TRUNC(SYSDATE, 'MONTH'), - 12) START_
        FROM
            DUAL
    )
CONNECT BY
    LEVEL <= 12 / ( &&INPUT_NUMBER );

-- 输入参数为2

SQL> SELECT
  2      ADD_MONTHS(START_,(LEVEL - 1) * &&INPUT_NUMBER) AS START_DATE,
  3      CASE
  4          WHEN LEVEL = 12 / ( &&INPUT_NUMBER ) THEN SYSDATE
  5          ELSE ADD_MONTHS(START_,(LEVEL) * &&INPUT_NUMBER)
  6      END AS END_DATE
  7  FROM
  8      (
  9          SELECT
 10              ADD_MONTHS(TRUNC(SYSDATE, 'MONTH'), - 12) START_
 11          FROM
 12              DUAL
 13      )
 14  CONNECT BY
 15      LEVEL <= 12 / ( &&INPUT_NUMBER )
 16  ;


START_DAT END_DATE
--------- ---------
01-AUG-18 01-OCT-18
01-OCT-18 01-DEC-18
01-DEC-18 01-FEB-19
01-FEB-19 01-APR-19
01-APR-19 01-JUN-19
01-JUN-19 27-AUG-19

6 rows selected.

SQL>

-- 输入参数为 3

SQL> SELECT
  2      ADD_MONTHS(START_,(LEVEL - 1) * &&INPUT_NUMBER) AS START_DATE,
  3      CASE
  4          WHEN LEVEL = 12 / ( &&INPUT_NUMBER ) THEN SYSDATE
  5          ELSE ADD_MONTHS(START_,(LEVEL) * &&INPUT_NUMBER)
  6      END AS END_DATE
  7  FROM
  8      (
  9          SELECT
 10              ADD_MONTHS(TRUNC(SYSDATE, 'MONTH'), - 12) START_
 11          FROM
 12              DUAL
 13      )
 14  CONNECT BY
 15      LEVEL <= 12 / ( &&INPUT_NUMBER )
 16  ;
Enter value for input_number: 3


START_DAT END_DATE
--------- ---------
01-AUG-18 01-NOV-18
01-NOV-18 01-FEB-19
01-FEB-19 01-MAY-19
01-MAY-19 27-AUG-19

SQL>

干杯!!


推荐阅读