NIby banalne ale jednak...
Jest taka tabela:
http://www.schulserver.hessen.de/darmstadt/lichtenberg/SQLTutorial/db_cia.html
Mam wystosowac zapytanie
"Pokaz nazwy regionow i to ile one krajow zawieraja"
Prawidlowe zapytanie wyglada tak:
SELECT Region, COUNT(Region)
FROM cia
GROUP BY Region
A ja nie wiem jak dziala group by na tej tabeli
:[
Kolejnosc wykonywania poleceni przez SQL jest taka:
1. FROM - jako pierwsze
2. WHERE - jako drugie itd
3. GROUP BY
4. HAVING
5. SELECT
6. ORDER BY
7. LIMIT
Mamy wiec jako pierwsze: FROM czyli tabele cia
NIe mamy WHERE wiec przechodzimy do GROUP BY
Co sie dzieje z tabela gdy robimy na niej to polecenie?
Ona sklada sie z takich kolumn:
Name Region Fläche Einwohner BIP
Jesli uzyje na niej GROUP BY to ona wycina Name czy nie?
No bo niby jak ma zgrupowac nazwy panstw dla Regionu Europy jak:
Polska, Niemcy, Irlandia?
Cyfry zgrupowac (zsumowac) to rozumiem, ale nazwy krajow?
Skoro wykonalem GROUP BY na tabeli i zsumowaly sie Powierzchnia
(Fläche), Mieszkancy (Einwohner) i PKB (BIP) to jak taka "wykastrowana"
tabela po GROUP BY moze wiedziec ile dany region zawiera panstw?!
Czegos tu nie kumam.
--
topek -> jak zawsze pozdrawiajacy
"Nie lubisz ty bratku swojej repliki,
gdy patrzysz na mnie w oczach masz kurwiki"
bo to co zwraca sql nie jest tabela tylko widokiem danych
masz dane -> operujesz na nich (przeksztalcasz je) => wyswietlasz.
funkcja count -> jest funkcja grupujaca(agregujace) zwraca ona akurat
wynik ilosci wystąpien danej wartosci w okreslonej kolumnie.
jeśli azja wystapi dwa razy to count(region) zwraca 2
group by sluzy do pobierania unikalnych wartosci które nie są objęte
funkcjami grupującymi.
przyczym zapytanie grupujace (uzywajace funkcji grupujacych lub group by)
unikalne dane traktuje jako jeden worek.
wiec jesli w kolumnie masz 10 roznych wartosci powstanie 10 workow na
ktorych beda operowac funkcje agregujące.
więc
select region,count(region) from jakastabela
group by region
dzieli dane na regiony i zlicza ilosc wystapien w kazdym worku.
jesli zrobisz
select Sum(BIP) from tabela
group by region
dostaniesz sumy BIP dla kazdego regionu
jesli zrobisz
select sum(BIP) from tabela
group by country
to dostaniesz sumy BIP dla kazdego kraju,
a jako ze w przykladzie kraje sa unikalne wiec suma bedzie odpowiadala
wartosci z kraju. ilosc workow bedzie rowna ilosci wierszy w tabeli.
a na koniec
select sum(BIP) from tabela
zroci jeden wynik bez podziałów,
nie zdefiniowano podzialu na worki
mam nadzieje ze wyraziłem się zrozumiale ;-)
Oczywiście użyte słownictwo jest pewnym uproszczeniem sprawy i w
rzeczywistości niekoniecznie tak musi to przebieg ale efekt jest taki
jak w opisie.
Pozdrawiam
J.
pomyśl o tym w ten sposób.
tabela to worek z rekordami. bez żadnej kolejności.
ty grupujesz. czyli:
lecisz po rekordach, i bierzesz nowy worek za każdym razem jak masz nową
wartośc w tym co grupujesz. po czym rekord wrzucasz do tego worka.
ilość worków == ilość grup.
każdy z worków zawiera jakąś tam część rekordów, ale każdy rekord
wystepuje tylko w jednym worku.
na to nakładamy pobieranie danych.
jeśli pobierasz daną po której grupowałeś, to po prostu "odczytujesz
etykietkę na worku".
ale jak pobierasz inne dane to musisz (w postgresie, w mysqlu nie, w
innych bazach nie wiem) powiedzieć - wartość z którego rekordu zwrócić -
a dokładniej - którą wartość.
np. min(pole) - zwróci ci wartość pole z tego rekirdu w którym to pole
ma najmniejszą wartość.
sum(pole) zwróci sumę wartości "pole" ze wszystkich rekordów w worku.
a count(*) zwróci ile jest rekordów w worku.
count(region) zadziała w tym przypadku tak jak count(*), ale trwa troche
dłużej (raczej nie dasz rady wykryć różnicy), i przy innych danych moze
generować dziwne wyniki - ogólnie: używa się count(*), chyba, że na 100%
, na pewno, wiesz, że chcesz count(pole) i *czemu* chcesz count(pole)
lepiej?
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
> bo to co zwraca sql nie jest tabela tylko widokiem danych
Ja caly czas myslalem, ze ten widok danych to jest modyfikowana
wyjsciowa tabela, ale dowiedzialem sie, ze group by rozbija na
pomniejsze tabele/widoki danych/worki :) (i like it)
> funkcja count -> jest funkcja grupujaca(agregujace) zwraca ona akurat
> wynik ilosci wystąpien danej wartosci w okreslonej kolumnie.
Tak to zrozumialem.
> jeśli azja wystapi dwa razy to count(region) zwraca 2
Rowniez zrozumiale
> group by sluzy do pobierania unikalnych wartosci które nie są objęte
> funkcjami grupującymi.
? Unikalne wartosci?
Co przez to rozumiesz...?
Chodzi Ci o to ze jesli w SELECT mam cos takiego:
SELECT kolumna1, agregacja(kolumna2)
FROM tabela
To musze uzyc GROUP BY na kolumna1 bo inaczej blad wywali?
> przyczym zapytanie grupujace (uzywajace funkcji grupujacych lub group by)
> unikalne dane traktuje jako jeden worek.
NIe wiem o co Ci chodzi z tymi unikalnymi danymi.
> wiec jesli w kolumnie masz 10 roznych wartosci powstanie 10 workow na
> ktorych beda operowac funkcje agregujące.
Czyli jak w kolumnie mam 10 Regionow (Azja, Europa, Oceania itd) to po
uzyciu GROUP BY na tej kolumnie (i przy okazji tabeli)
Powstaje mi jakby 10 osobnych tabel (workow) dla kazdego regionu, a do
kazdego z nich pakuje reszte danych?
Czyli jesli uzyje GROUP BY na Region to powstaje mi 10 Tabel/workow:
Np worek o nazwie Europa a w nim nazwy panstw, mieszkancy tych panstw,
ich PKB itd?
> więc
> select region,count(region) from jakastabela
> group by region
>
> dzieli dane na regiony i zlicza ilosc wystapien w kazdym worku.
To chyba to samo co powyzej napisalem?
:)
> jesli zrobisz
>
> select Sum(BIP) from tabela
> group by region
>
> dostaniesz sumy BIP dla kazdego regionu
A moge grupowac po regionie jesli nie mam go w SELECT wymienionego?
> a na koniec
>
> select sum(BIP) from tabela
> zroci jeden wynik bez podziałów,
> nie zdefiniowano podzialu na worki
To jest prosciutkie :)
> mam nadzieje ze wyraziłem się zrozumiale ;-)
Prawie :)
DZiekuje bardzo za wyczerpujacy post.
tak dokladnie
>
>> przyczym zapytanie grupujace (uzywajace funkcji grupujacych lub group by)
>> unikalne dane traktuje jako jeden worek.
> NIe wiem o co Ci chodzi z tymi unikalnymi danymi.
zobacz
select distinct region from tabela
oraz
select region from tabela
group by region
jak dasz group by na jakis wiersz to w wyniku masz unikalne wartosci
(zadna wartosc grupowana sie nie powtarza, chyba ze dasz kilka kolumn w
group by to wtedy te kolumny razem daja wartosc unikalna w wyniku).
select kolumna1,kolumna2,grupujaca(kolumna3) from tabela
group by kolumna1,kolumna2
to kombinacja kolumna1 i kolumna2 beda w wyniku unikalne (nie
powtarzajace sie)
>
>> wiec jesli w kolumnie masz 10 roznych wartosci powstanie 10 workow na
>> ktorych beda operowac funkcje agregujące.
> Czyli jak w kolumnie mam 10 Regionow (Azja, Europa, Oceania itd) to po
> uzyciu GROUP BY na tej kolumnie (i przy okazji tabeli)
> Powstaje mi jakby 10 osobnych tabel (workow) dla kazdego regionu, a do
> kazdego z nich pakuje reszte danych?
> Czyli jesli uzyje GROUP BY na Region to powstaje mi 10 Tabel/workow:
>
> Np worek o nazwie Europa a w nim nazwy panstw, mieszkancy tych panstw,
> ich PKB itd?
tak i jak agregujesz np ilosc mieszkancow
to zostanie ona policzona (zsumowana) dla wartosci z worka
select sum(ile_ludu),kontynent from tabela
group by kontynent
>> mam nadzieje ze wyraziłem się zrozumiale ;-)
> Prawie :)
> DZiekuje bardzo za wyczerpujacy post.
Spox F vat przyjdzie pocztą :-)
Pozdrawiam
J.
>> Chodzi Ci o to ze jesli w SELECT mam cos takiego:
>>
>> SELECT kolumna1, agregacja(kolumna2)
>> FROM tabela
>>
>> To musze uzyc GROUP BY na kolumna1 bo inaczej blad wywali?
>
> tak dokladnie
>
Najlepiej zapamietaj to w ten sposób, że wszystko czego nie ma w
funkcjach agregujących powinno znaleźć się w GROUP BY.
--
Cezary Grądys
czar...@wa.onet.pl
oczywiscie by cos znalazlo sie w group by nie musi byc pobierane do
widoku danych
np.:
select sum(wartosc),towar from pozycje
group by rok
pozdrawiam
J.
>> group by sluzy do pobierania unikalnych wartosci które nie są objęte
>> funkcjami grupującymi.
>? Unikalne wartosci?
>Co przez to rozumiesz...?
>
>Chodzi Ci o to ze jesli w SELECT mam cos takiego:
>
>SELECT kolumna1, agregacja(kolumna2)
>FROM tabela
>
>To musze uzyc GROUP BY na kolumna1 bo inaczej blad wywali?
Tak. W SELECT mogą wystąpić tylko kolumny, które są w GROUP BY (tj. gdy nie są
parametrami funkcji agregujacej).
>Czyli jak w kolumnie mam 10 Regionow (Azja, Europa, Oceania itd) to po
>uzyciu GROUP BY na tej kolumnie (i przy okazji tabeli)
>Powstaje mi jakby 10 osobnych tabel (workow) dla kazdego regionu, a do
>kazdego z nich pakuje reszte danych?
>Czyli jesli uzyje GROUP BY na Region to powstaje mi 10 Tabel/workow:
>
>Np worek o nazwie Europa a w nim nazwy panstw, mieszkancy tych panstw,
>ich PKB itd?
Nie, pozostaje tylko to co wymienisz w SELECT. Inne dane są "tracone" i nie ma
ich w wyniku i generalnie po grupowaniu nie ma możliwości dostępu do nich.
Innymi słowy jeśli pogrupujesz dane po regionie:
select region, count(region)
from kraje
group by region;
to nie wiesz, które konkretnie kraje składają się na dany region.
>A moge grupowac po regionie jesli nie mam go w SELECT wymienionego?
Kolumna po której grupujesz nie musi wystąpić w SELECT:
select count(*)
from kraje
group by region;
Ale oczywiście czytelniej jest wiedzieć ile krajów jest w danym regionie niż
tylko mieć same liczby:
2
4
7
15
20
...
--
Sławomir Szyszło
Primus inter FAQires & Grand Inquisitor no.0 of pl.comp.bazy-danych
FAQ pl.comp.bazy-danych http://www.dbf.pl/faq/
Archiwum http://groups.google.com/groups?group=pl.comp.bazy-danych
>oczywiscie by cos znalazlo sie w group by nie musi byc pobierane do
>widoku danych
>
>np.:
>
>select sum(wartosc),towar from pozycje
>group by rok
To akurat nie jest prawda. OIMW nie jest to zapytanie zgodne ze standardem SQL.
Takie coś przechodzi bodajże tylko w MySQL i ten "towar" to jest wartość z
bliżej nieokreślonego rekordu.
Inne bazy zwrócą błąd typu "TOWAR is not in GROUP BY clause".
przepraszam pomilem sie
chodzilo oczywiscie
ze w group by ma byc
towar,rok
>Ale tylko wtedy jestesmy zmuszeni do uzywania GROUP BY jesli w SELECT
>mamy jakas funkcje agregujaca.
No nie:
select sum(kwota)
from tabela;
:]
nie czuj się *zmuszany* do czegokolwiek.
np. w poprzednich wersjach postgresa:
select pole from table group by pole;
było używane zamiast:
select distinct pole from table;
tzn. daje ten sam wynik.
Best regards,