Z racji tego, że nowy rok się zbliża, postanowiłem napisać zapytanie, które zwraca dni w bieżącym miesiącu - taki kalendarzyk dla danego miesiąca. Poniżej jest przedstawiony kod. Proszę zauważyć, że pierwszy dzień tygodnia zaczyna się w niedzielę. Dla innej kultury będzie inne zapytanie.
with x
as (
select *
from (
select to_char(trunc(sysdate,'mm')+level-1,'iw') wk,
to_char(trunc(sysdate,'mm')+level-1,'dd') dm,
to_number(to_char(trunc(sysdate,'mm')+level-1,'d')) dw,
to_char(trunc(sysdate,'mm')+level-1,'mm') curr_mth,
to_char(sysdate,'mm') mth
from dual
connect by level <= 31
)
where curr_mth = mth
)
select max(case dw when 2 then dm end) Mo,
max(case dw when 3 then dm end) Tu,
max(case dw when 4 then dm end) We,
max(case dw when 5 then dm end) Th,
max(case dw when 6 then dm end) Fr,
max(case dw when 7 then dm end) Sa,
max(case dw when 1 then dm end) Su
from x
group by wk
order by wk
;
Dla miesiąca grudzień mamy taki wynik:
Niestety dla ostatnich dni roku (30 i 31 grudnia) mamy problem ze standaryzacją numerów miesiąca w roku. Dla tych dwóch ostatnich dni, numer tygodnia w roku jest 1 dla parametru IW (więcej o parametrach daty znajdują się w funkcji
to_char). Będziemy musieli skorzystać z parametru WW.
select *
from (
select to_char(trunc(sysdate,'mm')+level-1,'iw') wk,
to_number(to_char(trunc(sysdate,'mm')+level-1,'ww')) wn,
to_char(trunc(sysdate,'mm')+level-1,'dd') dm,
to_number(to_char(trunc(sysdate,'mm')+level-1,'d')) dw,
to_char(trunc(sysdate,'mm')+level-1,'mm') curr_mth,
to_char(sysdate,'mm') mth
from dual
connect by level <= 31
)
where curr_mth = mth
;
I na końcu wystarczy zgrupować
with x
as (
select *
from (
select to_char(trunc(sysdate,'mm')+level-1,'iw') wk,
to_number(to_char(trunc(sysdate,'mm')+level-1,'ww')) wn,
to_number(to_char(trunc(sysdate,'mm')+level-1,'dd')) dm,
to_number(to_char(trunc(sysdate,'mm')+level-1,'d')) dw,
to_char(trunc(sysdate,'mm')+level-1,'mm') curr_mth,
to_char(sysdate,'mm') mth
from dual
connect by level <= 31
)
where curr_mth = mth
)
select
--wk,
--max(wn) wna,
max(case dw when 2 then dm end) Mo,
max(case dw when 3 then dm end) Tu,
max(case dw when 4 then dm end) We,
max(case dw when 5 then dm end) Th,
max(case dw when 6 then dm end) Fr,
max(case dw when 7 then dm end) Sa,
max(case dw when 1 then dm end) Su
from x
group by wk
order by max(wn)
;
A rezultat takiego zapytania wygląda następująco: