2010-01-13

[psql] Grupowanie i funkcja min()

Funkcja min() PostgreSQL'a w połączniu z grupowaniem daje bardzo fajną użyteczność.
Załóżmy, że mamy trzy tabele: ojciec, dziecko i powiazanie. Jeden rodzic może mieć wiele dzieci:


create table ojciec(
id serial primary key,
nazwisko varchar(50),
imie varchar(50)
);

insert into ojciec (id, nazwisko, imie) VALUES ('1', 'KOWALSKI', 'JAN');
insert into ojciec (id, nazwisko, imie) VALUES ('2', 'MAŁYSZ', 'ADAM');

create table dziecko(
id serial primary key,
nazwisko varchar(50),
imie varchar(50)
);

insert into dziecko (id, nazwisko, imie) VALUES ('1', 'KOWALSKI', 'MATEUSZ');
insert into dziecko (id, nazwisko, imie) VALUES ('2', 'KOWALSKA', 'MONIKA');
insert into dziecko (id, nazwisko, imie) VALUES ('3', 'MAŁYSZ', 'WERONIKA');
insert into dziecko (id, nazwisko, imie) VALUES ('4', 'MAŁYSZ', 'ANNA');
insert into dziecko (id, nazwisko, imie) VALUES ('5', 'MAŁYSZ', 'MICHAŁ');

create table powiazanie(
id serial primary key,
ojciec_id int references ojciec(id),
dziecko_id int references dziecko(id)
);

insert into powiazanie (id, ojciec_id, dziecko_id) VALUES ('1', '1', '1');
insert into powiazanie (id, ojciec_id, dziecko_id) VALUES ('2', '1', '2');
insert into powiazanie (id, ojciec_id, dziecko_id) VALUES ('3', '2', '3');
insert into powiazanie (id, ojciec_id, dziecko_id) VALUES ('4', '2', '4');
insert into powiazanie (id, ojciec_id, dziecko_id) VALUES ('5', '2', '5');

Mamy zatem piatkę dzieciaków należącą do dwóch ojców:

 id | dzieciak | ojciec
----+------------------+--------------
1 | KOWALSKI MATEUSZ | KOWALSKI JAN
2 | KOWALSKA MONIKA | KOWALSKI JAN
3 | MAŁYSZ WERONIKA | MAŁYSZ ADAM
4 | MAŁYSZ ANNA | MAŁYSZ ADAM
5 | MAŁYSZ MICHAŁ | MAŁYSZ ADAM

Poniższe zapytanie sql pokaże w jaki sposób można wyciągnąć informacje o tym który dzieciak był najwcześniej wpisany (być może jest najstarszy ;])

select min(d.id) as najmlodszy_dzieciak, o.nazwisko || ' ' || o.imie as ojciec from ojciec o, dziecko d, powiazanie p where o.id=p.ojciec_id and d.id=p.dziecko_id group by ojciec;

wynik:

 najmlodszy_dzieciak | ojciec
---------------------+--------------
3 | MAŁYSZ ADAM
1 | KOWALSKI JAN

Funkcja min() dzięki swoim właściwościom pomogła mi dziś uporać się z jedną tabelą, w której znajdowały się zdublowane wiersze różniące się tylko id. Dzięki min() udało mi się z tym uporać - stąd ten wpis... na dobry początek... :)

5 komentarzy:

  1. a dlaczego kolumna ociec w wyniku zapytania jest pusta i co to są te || ' ' || ?

    OdpowiedzUsuń
  2. Poprzestawiało mi się całe formatowanie jak zacząłem się bawić edytorem WYSIWYG - dobra rada to nie używać tego... ;) Teraz z tym ojcem powinno być już bardziej przystępne... ;)

    Za pomocą || możliwe jest połączenie dwóch kolumn w jedną. Na przykład ojciec.imie || ojciec.nazwisko moze dac nam wynik KOWALSKIJAN (bez spacji). || ' ' || daje połączenie dwóch kolumn ze spacją w środku.

    OdpowiedzUsuń
  3. aaa.. lama ze mnie szybciej pisze niz mysle ;)

    OdpowiedzUsuń
  4. pozna pora - ja juz tez ledwo kontaktuje ;]

    OdpowiedzUsuń
  5. kiedys po prostu w mysql uzywalem concat(kolumnaa, ' ',kolumnab) a || to skojarzylo mi sie od razu z operatorem logicznym OR stad to moje zaklopotanie ale fakt - moglem sie tego domyslic.. pozna pora jak juz napisales

    OdpowiedzUsuń