SELECT dt
FROM (SELECT TRUNC(SYSDATE - 184) + LEVEL AS dt
FROM dual
CONNECT BY LEVEL <= 369)
WHERE dt BETWEEN add_months(TRUNC(SYSDATE), -6) AND add_months(TRUNC(SYSDATE), 6);
SQL> with
2 threeid (id, datum) as
3 (select 1, date '2020-05-29' from dual union all
4 select 2, date '2020-01-01' from dual union all
5 select 3, date '2020-02-29' from dual
6 ),
7 cal as
8 (select add_months(datum, -6) + column_value - 1 datum
9 from threeid cross join
10 table(cast(multiset(select level from dual
11 connect by level <= add_months(datum, 6) - add_months(datum, -6)
12 ) as sys.odcinumberlist))
13 where id = 1 --> for the 1st ID; change that for other calendars
14 )
15 select * from cal order by datum;
DATUM
----------
29.11.2019
30.11.2019
01.12.2019
02.12.2019
03.12.2019
<snip>
25.11.2020
26.11.2020
27.11.2020
28.11.2020
366 rows selected.
如果你想画出来,用这个代替15号线。。。
<snip>
15 select lpad(month, 20, ' ') month,
16 "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
17 from (select to_char(dt, 'fmMonthfm YYYY') month,
18 week,
19 max(decode(to_char(dt, 'd'), '1', lpad(to_char(dt, 'fmdd'), 2))) "Mon",
20 max(decode(to_char(dt, 'd'), '2', lpad(to_char(dt, 'fmdd'), 2))) "Tue",
21 max(decode(to_char(dt, 'd'), '3', lpad(to_char(dt, 'fmdd'), 2))) "Wed",
22 max(decode(to_char(dt, 'd'), '4', lpad(to_char(dt, 'fmdd'), 2))) "Thu",
23 max(decode(to_char(dt, 'd'), '5', lpad(to_char(dt, 'fmdd'), 2))) "Fri",
24 max(decode(to_char(dt, 'd'), '6', lpad(to_char(dt, 'fmdd'), 2))) "Sat",
25 max(decode(to_char(dt, 'd'), '7', lpad(to_char(dt, 'fmdd'), 2))) "Sun"
26 from ( select dt,
27 case when dt >= to_date(to_char(dt, 'dd/') ||'12/'||
28 to_char(sysdate,'yyyy'), 'dd/mm/yyyy')
29 and wk = '01'
30 then '53'
31 else wk
32 end week
33 from (select datum dt, to_char(datum, 'iw') wk
34 from cal
35 )
36 )
37 group by to_char(dt, 'fmMonthfm YYYY'), week
38 )
39 order by to_date( month, 'Month YYYY' ), to_number(week);
... 然后得到:
MONTH Mon Tue Wed Thu Fri Sat Sun
-------------------- -------- -------- -------- -------- -------- -------- --------
November 2019 29 30
December 2019 30 31
December 2019 1
December 2019 2 3 4 5 6 7 8
December 2019 9 10 11 12 13 14 15
December 2019 16 17 18 19 20 21 22
December 2019 23 24 25 26 27 28 29
January 2020 1 2 3 4 5
January 2020 6 7 8 9 10 11 12
January 2020 13 14 15 16 17 18 19
January 2020 20 21 22 23 24 25 26
January 2020 27 28 29 30 31
February 2020 1 2
February 2020 3 4 5 6 7 8 9
February 2020 10 11 12 13 14 15 16
February 2020 17 18 19 20 21 22 23
February 2020 24 25 26 27 28 29
March 2020 1
March 2020 2 3 4 5 6 7 8
March 2020 9 10 11 12 13 14 15
March 2020 16 17 18 19 20 21 22
March 2020 23 24 25 26 27 28 29
March 2020 30 31
April 2020 1 2 3 4 5
April 2020 6 7 8 9 10 11 12
April 2020 13 14 15 16 17 18 19
April 2020 20 21 22 23 24 25 26
April 2020 27 28 29 30
May 2020 1 2 3
May 2020 4 5 6 7 8 9 10
May 2020 11 12 13 14 15 16 17
May 2020 18 19 20 21 22 23 24
May 2020 25 26 27 28 29 30 31
June 2020 1 2 3 4 5 6 7
June 2020 8 9 10 11 12 13 14
June 2020 15 16 17 18 19 20 21
June 2020 22 23 24 25 26 27 28
June 2020 29 30
July 2020 1 2 3 4 5
July 2020 6 7 8 9 10 11 12
July 2020 13 14 15 16 17 18 19
July 2020 20 21 22 23 24 25 26
July 2020 27 28 29 30 31
August 2020 1 2
August 2020 3 4 5 6 7 8 9
August 2020 10 11 12 13 14 15 16
August 2020 17 18 19 20 21 22 23
August 2020 24 25 26 27 28 29 30
August 2020 31
September 2020 1 2 3 4 5 6
September 2020 7 8 9 10 11 12 13
September 2020 14 15 16 17 18 19 20
September 2020 21 22 23 24 25 26 27
September 2020 28 29 30
October 2020 1 2 3 4
October 2020 5 6 7 8 9 10 11
October 2020 12 13 14 15 16 17 18
October 2020 19 20 21 22 23 24 25
October 2020 26 27 28 29 30 31
November 2020 1
November 2020 2 3 4 5 6 7 8
November 2020 9 10 11 12 13 14 15
November 2020 16 17 18 19 20 21 22
November 2020 23 24 25 26 27 28
64 rows selected.
SQL>
2条答案
按热度按时间vd8tlhqk1#
“月”的概念是可变的,所以你可能需要再次检查“6个月”是否真的是你想要的。如果你不知道日期数学的奇怪之处,它会产生意想不到的结果。
也就是说,在当前日期的两边都包含6个月的日历可以用以下公式生成。请注意,184天是6个月(7月至12月)所能持续的最长时间。
drkbr07n2#
照你说的做:有一个表有3个ID和它们的日期,你想绘制日历。
使用分层查询,日期生成为
如果你想画出来,用这个代替15号线。。。
... 然后得到:
(这个不错的日历查询最初(至少,我认为是这样)发布在orafaq网站上;我调整了它,希望它能正确显示日期)