我有一个要求
START_DATE : 03/01/2018
END_DATE : 28/12/2018
我需要一个查询,列出这两个日期之间的所有月份开始日期和结束日期,如下所示
StartMonth EndMonth
03/01/2018 31/01/2018
01/02/2018 28/01/2018
01/03/2018 31/03/2018
01/04/2018 30/04/2018
01/05/2018 31/05/2018
01/06/2018 30/06/2018
01/07/2018 31/07/2018
01/08/2018 31/08/2018
01/09/2018 30/09/2018
01/10/2018 31/10/2018
01/11/2018 30/11/2018
01/12/2018 28/12/2018
我还需要一个查询,列出这两个日期之间所有季度的开始日期和结束日期,如下所示
StartQuarter EndQuarter
03/01/2018 31/03/2018
01/04/2018 30/06/2018
01/07/2018 30/09/2018
01/10/2018 28/12/2018
答案 0 :(得分:1)
这些应该有用。
几个月:
select greatest(:start_date, trunc(add_months( :start_date, level - 1), 'MON')) as startmonth,
least(:end_date, last_day(add_months( :start_date, level - 1))) as endmonth
from dual
connect by level <= trunc(months_between(trunc( :end_date, 'MON'), trunc( :start_date, 'MON'))) + 1;
对于季度:
select greatest(:start_date, trunc(add_months( :start_date, 3 * (level - 1)), 'Q')) as startmonth,
least(:end_date, last_day(add_months( :start_date, 3 * (level - 1) + 2))) as endmonth
from dual
connect by level <= trunc(months_between(trunc( :end_date, 'Q'), trunc( :start_date, 'Q'))) / 3 + 1;
其中:start_date和:end_date是您的开始和结束日期。
答案 1 :(得分:0)
这里的变体并不限于任何特定的范围长度:
SELECT TO_CHAR(GREATEST(
LAST_DAY(ADD_MONTHS(:start_date, LEVEL - 2)) + 1,
:start_date
), 'dd/mm/yyyy') AS StartMonth,
TO_CHAR(LEAST(
:end_date,
LAST_DAY(ADD_MONTHS(:start_date, LEVEL - 1))
), 'dd/mm/yyyy') AS EndMonth
FROM dual
CONNECT BY LAST_DAY(ADD_MONTHS(:start_date, LEVEL - 1)) <= LAST_DAY(:end_date);
编辑:修正开始日期范围后,它看起来非常像接受的答案,使用不同的日期算术方式。对于每季度,@ GriffeyDog使用TRUNC
可能是最好的选择。
答案 2 :(得分:0)
这是一个生成月度条目的CTE(公用表表达式):
WITH
aset
AS
(SELECT DATE '2018-01-03' start_month, DATE '2018-12-28' last_month
FROM DUAL),
bset (start_month, end_month, last_month)
AS
(SELECT start_month, LEAST (ADD_MONTHS (TRUNC (start_month, 'MM'), 1) - 1, last_month) end_month, last_month
FROM aset
UNION ALL
SELECT ADD_MONTHS (TRUNC (start_month, 'MM'), 1)
, LEAST (ADD_MONTHS (start_month, 2) - 1, last_month)
, last_month
FROM bset
WHERE end_month < last_month)
SELECT start_month, end_month
FROM bset;
START_MONTH END_MONTH
----------- ---------
03-JAN-18 31-JAN-18
01-FEB-18 02-MAR-18
01-MAR-18 31-MAR-18
01-APR-18 30-APR-18
01-MAY-18 31-MAY-18
01-JUN-18 30-JUN-18
01-JUL-18 31-JUL-18
01-AUG-18 31-AUG-18
01-SEP-18 30-SEP-18
01-OCT-18 31-OCT-18
01-NOV-18 30-NOV-18
01-DEC-18 28-DEC-18