Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Postgres numer tygodnia w miesiącu.

244 views
Skip to first unread message

Cezary Grądys

unread,
Jan 24, 2011, 4:36:06 PM1/24/11
to
Witam.
Nie mogę się doszukać, czy może jest w Postgresie funkcja podająca nr
tygodnia w miesiącu dla danej daty? Chodzi mi o to, żeby jeśli 1 jest w
niedzielę, to drugiego jest już drugi tydzień.
Na raziew znalazłem funkcję to_char, ale widzę tylko możliwość liczenia
tygodnia od 1 do 7 jako pierwszy, 8 -14 jako 2 itp.

select to_char('2011-01-01'::date, 'W');
to_char
---------
1


test=> select to_char('2011-01-03'::date, 'W');
to_char
---------
1 -- tu bym chciał otrzymać 2


Czy jestem zmuszony kombinować z obliczaniem numeru tygodnia w roku i
odejmowaniem numeru tygodnia początku miesiąca, czy może jest coś
gotowego? W dodatku 1 stycznia bierzącego roku to tydzień 52 co troche
komplikuje obliczenia ;)

--
Cezary Grądys
czar...@wa.onet.pl

Marek

unread,
Jan 24, 2011, 5:00:59 PM1/24/11
to
Czy takie kalkulacje nie powinny odbywać się poziom wyżej: w aplikacji?

hubert depesz lubaczewski

unread,
Jan 24, 2011, 5:16:37 PM1/24/11
to

moment.
widzę tu pewne zamieszanie.
numer tygodnia w miesiącu, czy w roku?

jak w tygodniu, to użycie to_char(... , 'W') ma pewien sens, and wtedy
liczba 52 nie ma sensu (nie ma miesiąca mającego 52 tygodnie).

jeśli chcesz numer tygodnia w roku - użyj extract(week from ...)

depesz

--
Linkedin: http://www.linkedin.com/in/depesz / blog: http://www.depesz.com/
jid/gtalk: dep...@depesz.com / aim:depeszhdl / skype:depesz_hdl / gg:6749007

Cezary Grądys

unread,
Jan 25, 2011, 12:54:01 AM1/25/11
to
W dniu 24.01.2011 23:16, hubert depesz lubaczewski pisze:

> moment.
> widzę tu pewne zamieszanie.
> numer tygodnia w miesiącu, czy w roku?
>
> jak w tygodniu, to użycie to_char(... , 'W') ma pewien sens, and wtedy
> liczba 52 nie ma sensu (nie ma miesiąca mającego 52 tygodnie).
>
> jeśli chcesz numer tygodnia w roku - użyj extract(week from ...)
>
> depesz
>

Trochę niejasno napisałem. Chodzi o nr tygodnia w miesiecu.
Ale liczony tak, że tydzień zaczyna się w poniedziałek a kończe w
niedziele. Może być nawet tydzień 1 dniowy jak 28 luty 2011 (5 tydzień
lutego - poniedziałek). Po prostu od "wieków" tak robili raport i lepiej
tak zostawić.
O numerach tygodni w roku wspomniałem dlatego, że można próbować odjąć
numer tygodnia początku miesiąca, od numeru bierzącego tygodnia.

--
Cezary Grądys
czar...@wa.onet.pl

Cezary Grądys

unread,
Jan 25, 2011, 1:00:15 AM1/25/11
to
W dniu 24.01.2011 23:00, Marek pisze:

> Czy takie kalkulacje nie powinny odbywać się poziom wyżej: w aplikacji?

Na pewno nie w tym przypadku. Robię raport comiesieczny z wykonanych
zleceń. Plik mam w formacie Accessa, konwertuję go mdb-export do
postgresa. To robota zupełnie dodatkowa i nie na temat w firmie w której
pracuję. W sumie już napisałem zapytania w Accessie, ale chcę to puścić
w skrypcie, żeby nie musieć pamietać co trzeba po kolei robić i z
jakiego pliku.

--
Cezary Grądys
czar...@wa.onet.pl

hubert depesz lubaczewski

unread,
Jan 25, 2011, 3:30:04 AM1/25/11
to

a jaki numer tygodnia chcesz dla 1 lutego 2011 (wtorek)?

Michal Jankowski

unread,
Jan 25, 2011, 4:03:11 AM1/25/11
to
Cezary Grądys <czar...@wa.onet.pl> writes:

> Nie mogę się doszukać, czy może jest w Postgresie funkcja podająca nr
> tygodnia w miesiącu dla danej daty? Chodzi mi o to, żeby jeśli 1 jest
> w niedzielę, to drugiego jest już drugi tydzień.

floor((date_part('day',termin)+date_part('isodow',date_trunc('month', termin))+5)/7)

(gdzie 'termin' jest datą, o którą pytamy).

MJ

Marek

unread,
Jan 25, 2011, 9:37:27 AM1/25/11
to

Rozumiem ... może trochę off-topic - po co taka kombinacja? Czy sam Access
nie jest na tyle wystarczający? Tak czy owak robisz ręczną robotę z
eksportowaniem danych. Robiłem dawno temu jakieś analizy danych właśnie w
Accessie. Napisałem wtedy szybko skrypcik w VB, który generował pięknie
wyglądający raport gotowy do druku. Potem za każdym razem wystarczyło, że
kliknąłem na ikonce tego skryptu, podałem przedział czasowy w oknie
dialogowym (parametry analizy) i koniec roboty. Na upartego można
zasymulować działanie skryptu podobne do aplikacji desktopowej.

Cezary Grądys

unread,
Jan 25, 2011, 2:01:21 PM1/25/11
to
W dniu 25.01.2011 09:30, hubert depesz lubaczewski pisze:

> a jaki numer tygodnia chcesz dla 1 lutego 2011 (wtorek)?
>
> depesz
>

1.

Czyli coś takiego:
2011-01-28 | sob | 5
2011-01-29 | niedz | 5
2011-01-31 | pon | 6 -- tydzień 1 dniowy ;)
2011-02-01 | wto | 1 -- początek tygodnia 6 dniowego ;)
.....
2011-02-06 | niedz | 1
2011-02-07 | pon | 2
...... -- kilka tygodni 7 dniowych
2011-02-28 | niedz | 4
2011-02-28 | pon | 5 -- znowu tydzień 1 dniowy,
w dodatku luty ma 28 dni, czyli 5 tygodni ;)

W accessie znalazłem taką funkcję, teraz nie pamietam nazwy.
Chyba zrobię tak, że obliczę nr dnia powiedzmy od epoki, dodam/odejmę
pewną liczbę (1..6), podzielę praz 7. Otrzymam nr tygodnia od wybranej
daty, dodam 1 i odejmę tak samo liczony numer dla początku miesiąca.

Michal Jankowski

unread,
Jan 25, 2011, 3:14:09 PM1/25/11
to
Cezary Grądys <czar...@wa.onet.pl> writes:

> W accessie znalazłem taką funkcję, teraz nie pamietam nazwy.

Przecież podałem gotowy wzór. Po co ja to piszę, skoro nikt nie
czyta...

MJ

Cezary Grądys

unread,
Jan 25, 2011, 3:22:37 PM1/25/11
to
W dniu 25.01.2011 15:37, Marek pisze:

> Rozumiem ... może trochę off-topic - po co taka kombinacja? Czy sam Access
> nie jest na tyle wystarczający? Tak czy owak robisz ręczną robotę z
> eksportowaniem danych. Robiłem dawno temu jakieś analizy danych właśnie w
> Accessie. Napisałem wtedy szybko skrypcik w VB, który generował pięknie
> wyglądający raport gotowy do druku. Potem za każdym razem wystarczyło, że
> kliknąłem na ikonce tego skryptu, podałem przedział czasowy w oknie
> dialogowym (parametry analizy) i koniec roboty. Na upartego można
> zasymulować działanie skryptu podobne do aplikacji desktopowej.

Bo nie znam Accessa, bo trzeba by go zamówić, bo plik mdb jest stary i
nie wiadomo jak go zinterpretuje nowa wersja (stara już krzyczy, że jest
w poprzedniej wersji), bo już robię 1 raport za pomocą postgresa.
Jeszcze w tej wersji co próbuję access nie przyjmuje podwójnego minusa
jako komentarz!!!
No i subiektywne powody, mam sentyment do postgresa, jakoś mi pasuje.
Ale na pewno jakbym znał Accessa trochę, to bym nie przenosił. Bo pewne
problemy doszły: kodowanie i ten numer tygodnia.

Cezary Grądys

unread,
Jan 25, 2011, 3:25:51 PM1/25/11
to czar...@wa.onet.pl
W dniu 25.01.2011 10:03, Michal Jankowski pisze:


Dzięki, wygląda po pierwszych próbach, że jest OK. Jutro potestuje.
Myślałem o czymś w tym stylu, ale liczyłem, że może jest gotowa funkcja.
Serdeczne dzięki.

Michal Jankowski

unread,
Jan 25, 2011, 3:26:10 PM1/25/11
to Cezary Grądys
Cezary Grądys <czar...@wa.onet.pl> writes:

> No i subiektywne powody, mam sentyment do postgresa, jakoś mi pasuje.
> Ale na pewno jakbym znał Accessa trochę, to bym nie przenosił. Bo
> pewne problemy doszły: kodowanie i ten numer tygodnia.

Halo, czy ktoś mnie słyszy??? Wzór podałem gotowy...

MJ

Cezary Grądys

unread,
Jan 25, 2011, 3:31:13 PM1/25/11
to
W dniu 25.01.2011 21:14, Michal Jankowski pisze:

> Przecież podałem gotowy wzór. Po co ja to piszę, skoro nikt nie
> czyta...
>
> MJ

Czyta, ale nie w tej kolejności :)
Dzięki, ten wzór jest tym o co chodziło.

hubert depesz lubaczewski

unread,
Jan 25, 2011, 3:53:40 PM1/25/11
to
On 2011-01-25, Cezary Grądys <czar...@wa.onet.pl> wrote:
> W dniu 25.01.2011 09:30, hubert depesz lubaczewski pisze:
>
>> a jaki numer tygodnia chcesz dla 1 lutego 2011 (wtorek)?
>>
>> depesz
>>
>
> 1.
>
> Czyli coś takiego:
> 2011-01-28 | sob | 5
> 2011-01-29 | niedz | 5
> 2011-01-31 | pon | 6 -- tydzień 1 dniowy ;)
> 2011-02-01 | wto | 1 -- początek tygodnia 6 dniowego ;)
> .....
> 2011-02-06 | niedz | 1
> 2011-02-07 | pon | 2
> ...... -- kilka tygodni 7 dniowych
> 2011-02-28 | niedz | 4
> 2011-02-28 | pon | 5 -- znowu tydzień 1 dniowy,
> w dodatku luty ma 28 dni, czyli 5 tygodni ;)
>

proszę bardzo:

CREATE function magic_week_number(DATE) RETURNS INT4 AS $$
SELECT ceil( ( extract(day from $1) + extract(isodow from date_trunc('month', $1) ) - 1 ) / 7 )::int4;
$$ language sql;

SELECT
x,
magic_week_number(x)
FROM
( VALUES
( '2011-01-28'::date ),
( '2011-01-29' ),
( '2011-01-31' ),
( '2011-02-01' ),
( '2011-02-06' ),
( '2011-02-07' ),
( '2011-02-27' ),
( '2011-02-28' )
) as v (x)
ORDER BY x;

wynik:

x | magic_week_number
------------+-------------------
2011-01-28 | 5
2011-01-29 | 5
2011-01-31 | 6
2011-02-01 | 1
2011-02-06 | 1
2011-02-07 | 2
2011-02-27 | 4
2011-02-28 | 5
(8 rows)

Marek

unread,
Jan 26, 2011, 10:02:56 AM1/26/11
to
Dnia Tue, 25 Jan 2011 21:22:37 +0100, Cezary Grądys napisał(a):

> Bo nie znam Accessa,

Hmmm ... nauka generowania raportów trwa zwykle krócej niż przeniesienie
danych do Postgresa :-)

> bo trzeba by go zamówić,

W sensie, że nie masz tej aplikacji? Jeśli tak, to faktycznie jest to
skuteczna przeszkoda, rozumiem więc Twój trud :-) Poniższy dialog ma sens
jeśli dostęp do Accessa uzyskałbyś.

> bo plik mdb jest stary i
> nie wiadomo jak go zinterpretuje nowa wersja (stara już krzyczy, że jest
> w poprzedniej wersji),

Tym się nie przejmuj. Zasysyałem stare bazy bez kłopotu.

> bo już robię 1 raport za pomocą postgresa.

Czas poświęcony na drugi raport pewnie będzie 10x większy niż wygenerowanie
go pod Accessem wliczając samoedukację :-)

> Jeszcze w tej wersji co próbuję access nie przyjmuje podwójnego minusa
> jako komentarz!!!

Nie załapałem jakie ma to znaczenie w raportach ale chyba nie jest istotne
dla naszej dyskusji.

> No i subiektywne powody, mam sentyment do postgresa, jakoś mi pasuje.

Ja również. Pracuję pod nim od wielu lat. Jednakże mimo to jeśli jest
możliwość oczywiście - używałbym właściwszych narzędzi do celów jak w/w.
Access to nie tylko baza ale i narzędzie do błyskawicznego tworzenia
raportów a także do pisania quasi-aplikacji.

> Ale na pewno jakbym znał Accessa trochę, to bym nie przenosił. Bo pewne
> problemy doszły: kodowanie i ten numer tygodnia.

I wiele innych, których jeszcze nie napotkałeś w tym raporcie, ale w innym
być może napotkasz ;-)

Cezary Grądys

unread,
Jan 26, 2011, 4:15:41 PM1/26/11
to
W dniu 25.01.2011 21:53, hubert depesz lubaczewski pisze:

> proszę bardzo:
>
> CREATE function magic_week_number(DATE) RETURNS INT4 AS $$
> SELECT ceil( ( extract(day from $1) + extract(isodow from date_trunc('month', $1) ) - 1 ) / 7 )::int4;
> $$ language sql;
>

Dzięki, czyli jednak gotowej funkcji nie ma.

--
Cezary Grądys
czar...@wa.onet.pl

Cezary Grądys

unread,
Jan 26, 2011, 4:40:46 PM1/26/11
to
W dniu 26.01.2011 16:02, Marek pisze:

> W sensie, że nie masz tej aplikacji? Jeśli tak, to faktycznie jest to
> skuteczna przeszkoda, rozumiem więc Twój trud :-) Poniższy dialog ma sens
> jeśli dostęp do Accessa uzyskałbyś.
>

No nie ma. Jest zainstalowany office, ale bez accessa, trzeba by się
prosić i potem czekać.


>> Jeszcze w tej wersji co próbuję access nie przyjmuje podwójnego minusa
>> jako komentarz!!!
>
> Nie załapałem jakie ma to znaczenie w raportach ale chyba nie jest istotne
> dla naszej dyskusji.
>

Często używam tych minusów do wyłączenia czegoś co źle działa, testowych
warunków, pól zbędnych, a zajmujących ekran przy testowaniu itp. No i
warto jakiś opis wrzucić. Dla mnie wywalenie błędu na 2 minusach to był
szok, tego się nie spodziewałem.


>> Ale na pewno jakbym znał Accessa trochę, to bym nie przenosił. Bo pewne
>> problemy doszły: kodowanie i ten numer tygodnia.
>
> I wiele innych, których jeszcze nie napotkałeś w tym raporcie, ale w innym
> być może napotkasz ;-)

Napotkałem inne traktowanie NULL np:
test=> select 'Ala ma kota' || NULL;
?column?
----------

(1 row)

Access wypisze 'Ala ma kota' .

Ale zapytanie w postgresie wygląda prościej mimo wszystko.
Potrzebowałem wydzielić fragment pola, w postgresie za pomocą wyrażeń
regularnych jest to względnie proste.
Czas mam, nikt mnie nie goni traktuję to jako naukę.

--
Cezary Grądys
czar...@wa.onet.pl

0 new messages