Oracle/PLSQL – zrób sobie kalendarz

Przygotujcie stare gazety, klej, papier, mazaki i nożyczki.

Czasem trzeba wykazać coś, czego nie było. Przykład? Lekarz wykonał w miesiącu kilkanaście porad. Jak pokazać syntetyczne to wykonanie na planie miesiąca? Tak, żeby było widać wszystkie dni, również te, w których nie pracował.

Najprościej wziąć jakąś tabelę. Intuicja mi podpowiada, że to powinna być słabo przyrastająca tabela. Nie znam się na tym na tyle, żeby wam wyjaśnić fachowo, dlaczego. Roboczo nazwę ją stare_gazety. Jeśli macie w swojej bazie tabelę o takiej nazwie, nic już nie musicie zmieniać! Oto jedno z niewielu rozsądnych zastosowań ROWNUM. Potrzebna nam konkretna ilość wierszy. Zaczynajmy.

Mamy jakąś datę? Weźmy dzisiejszą.

select sysdate dt from dual

Miesiąc, w którym siedzi ta data zaczyna się datą pole1 i ma dni pole2:

with d as (select sysdate dt from dual) 
select 
trunc(d.dt,'mm') pole1 ,
to_char(LAST_DAY(d.dt),'dd') pole2 
from d

Teraz bierzemy stare gazety i nożyczki i z tego robimy sobie takie coś:

with d as (select sysdate dt from dual)  
select rownum, 
to_char(trunc(d.dt,'mm') + rownum -1,'yyyy-mm-dd') data, to_char(trunc(d.dt,'mm') + rownum -1,'Day') dzien 
from stare_gazety tb
join d on 1=1 where rownum <=to_char(LAST_DAY(d.dt),'dd')

Wynik jest oszałamiający:

ROWNUMDATADZIEN
12019-10-01Wtorek
22019-10-02Środa
32019-10-03Czwartek
42019-10-04Piątek
52019-10-05Sobota
62019-10-06Niedziela
72019-10-07Poniedziałek
82019-10-08Wtorek
92019-10-09Środa
102019-10-10Czwartek
112019-10-11Piątek
122019-10-12Sobota
132019-10-13Niedziela
142019-10-14Poniedziałek
152019-10-15Wtorek
162019-10-16Środa
172019-10-17Czwartek
182019-10-18Piątek
192019-10-19Sobota
202019-10-20Niedziela
212019-10-21Poniedziałek
222019-10-22Wtorek
232019-10-23Środa
242019-10-24Czwartek
252019-10-25Piątek
262019-10-26Sobota
272019-10-27Niedziela
282019-10-28Poniedziałek
292019-10-29Wtorek
302019-10-30Środa
312019-10-31Czwartek

Tyle dni, a tylko cztery poniedziałki…

Teraz można wyświetlić dni pracy lekarza za pomocą złączenia jego tabeli praca z poprzednim zapytaniem SQL, nazywając je np. kalendarzem:

select kalendarz.data, count(praca.id) 
from kalendarz left join praca on kalendarz.data = praca.data
group by kalendarz.data 

Złączenie left join spowoduje, że zostaną wstawione do wyniku wszystkie dni z kalendarza i liczba porad lekarza w danym dniu. Banalne, prawda? Ale dopiero po opisaniu tego, umiem to w końcu zrobić.

A tu macie gotowy, jeśli nie chce wam się dłubać w SQL:

Ten wpis został opublikowany w kategorii SQL i oznaczony tagami , , . Dodaj zakładkę do bezpośredniego odnośnika.

Co o tym myślisz?

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj /  Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj /  Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj /  Zmień )

Połączenie z %s