Cytat
wydaje mi się, że najpierw zostaje "wyciągnięta" żądana liczba rekordów, a dopiero później zostają one pogrupowane.
Inaczej: najpierw zostają wyciągnięte rekordy (a nie ich liczba), a następnie zostają one pogrupowane według jakiejś kolumny.
W połączeniu z grupowaniem można użyć funkcji podsumowujących (agregujących) takich jak COUNT, AVG, SUM, MAX, MIN itp. Wówczas funkcje te będą dotyczyć rekordów o "wspólnej" wartości kolumny, którą grupowaliśmy.
Przykład:
[sql:1:7296594956]create table oceny
(
nazwisko varchar(255),
przedmiot varchar(255),
ocena int
);
insert into oceny (nazwisko, przedmiot, ocena) values
('Kowalski', 'mat', 3),('Nowak', 'mat', 3),('Iksinski', 'mat', 2),
('Kowalski', 'pol', 6),('Nowak', 'pol', 5),('Iksinski', 'pol', 5),
('Kowalski', 'geo', 3),('Nowak', 'geo', 4),('Iksinski', 'geo', 4),
('Kowalski', 'fiz', 4),('Nowak', 'fiz', 4),('Iksinski', 'fiz', 4),
('Kowalski', 'his', 2),('Nowak', 'his', 3),('Iksinski', 'his', 4),
('Kowalski', 'bio', 4),('Nowak', 'bio', 6),('Iksinski', 'bio', 4)
[/sql:1:7296594956]
Srednia kazdego ucznia (lista par: ("uczen", "srednia")):
[sql:1:7296594956]select nazwisko, avg(ocena) as srednia from oceny group by nazwisko;[/sql:1:7296594956]
To samo posortowane według nazwisk:
[sql:1:7296594956]select nazwisko, avg(ocena) as srednia from oceny group by nazwisko order by nazwisko;[/sql:1:7296594956]
Standardowe odchylenie ocen każdego z uczniów (lista par: ("uczeń", "st. odch. ocen ucznia"):
[sql:1:7296594956]select nazwisko, std(ocena) as odchylenie from oceny group by nazwisko order by nazwisko;[/sql:1:7296594956]
Aby otrzymać globalną srednią szkoły:
[sql:1:7296594956]select avg(ocena) as srednia from oceny;[/sql:1:7296594956]
Pierwsza dziesiątka uczniów:
[sql:1:7296594956]select nazwisko, avg(ocena) as srednia from oceny group by nazwisko order by srednia desc limit 10;[/sql:1:7296594956]
(oczywiście jest to prymitywne wybranie pierwszej dziesiątki; może być więcej uczniów, którzy mają średnią w pierwszej dziesiątce średnich).
Mozemy tez wyciagnac globalną średnią kazdego przedmiotu i utworzyć ranking od najlepszego przedmiotu do najgorszego:
[sql:1:7296594956]select przedmiot, avg(ocena) as srednia from oceny group by przedmiot order by srednia desc;[/sql:1:7296594956]
albo sprawdzić, ilu uczniów otrzymało każdą z ocen 1-6 z każdego przedmiotu (lista: ("ocena", "przedmiot", "liczba uczniów z taką oceną z tego przedmiotu"), z wyjątkiem ocen, które nie wystąpiły w danym przedmiocie):
[sql:1:7296594956]select przedmiot, ocena, count(nazwisko) as liczba_uczniow from oceny group by ocena, przedmiot;[/sql:1:7296594956]
To samo, posortowane malejąco według liczby uczniów:
[sql:1:7296594956]select przedmiot, ocena, count(nazwisko) as liczba_uczniow from oceny group by ocena, przedmiot order by liczba_uczniow desc;[/sql:1:7296594956]
To samo po odrzuceniu tych ocen, które w danym przedmiocie wystąpiły pojedynczo (klauzula
HAVING):
[sql:1:7296594956]select przedmiot, ocena, count(nazwisko) as liczba_uczniow from oceny group by ocena, przedmiot
HAVING liczba_uczniow > 1 order by liczba_uczniow desc[/sql:1:7296594956]
Prosty przykład 2 - zapytanie do dwóch tabel:
[sql:1:7296594956]create table dzialy
(
id_dzialu int,
nazwa varchar(255)
);
create table pracownicy
(
nazwisko varchar(255),
id_dzialu int,
zarobki int
);
insert into dzialy values (1, 'logistyka'),(2, 'kadry'),(3, 'produkcja');
insert into pracownicy values ('aaa', 1, 123),('bbb', 2, 421),('ccc', 1, 45),('ddd', 3, 531),('eee', 2, 52);
[/sql:1:7296594956]
Srednie zarobki w kazdym dziale (lista par: ("nazwa działu", "zarobki")):
[sql:1:7296594956]select dzialy.nazwa AS nazwa_dzialu, avg(pracownicy.zarobki) AS srednie_zarobki from dzialy, pracownicy where dzialy.id_dzialu = pracownicy.id_dzialu group by dzialy.id_dzialu [/sql:1:7296594956]
To samo co wyzej plus liczba pracownikow w danym dziale:
[sql:1:7296594956]select dzialy.nazwa AS nazwa_dzialu, avg(pracownicy.zarobki) AS srednie_zarobki, count(pracownicy.nazwisko) AS liczba_pracownikow from dzialy, pracownicy where dzialy.id_dzialu = pracownicy.id_dzialu group by pracownicy.id_dzialu [/sql:1:7296594956]
Pamiętaj o tym, że MySQL (inne systemy raczej też) nie lubi, jeśli po nazwach funkcji występuje odstęp.
Grupowanie jest trudne do wyjaśnienia, sam miewam problemy z poprawnym zastosowaniem w bardziej rozbudowanych zapytaniach, zwłaszcza, jeśli zapytanie odbywa się do wielu tabel. Pozostaje eksperymentować.