Porządkowanie wyniku zapytania klauzulą ORDER BY – kierunek ASC i DESC, sortowanie po kilku kolumnach, aliasie i pułapka tekst vs liczba.
Wynik zapytania nie ma z góry ustalonej kolejności. Baza zwraca wiersze w takiej, jaka jest dla niej najwygodniejsza – i ta kolejność potrafi się zmienić między jednym a drugim uruchomieniem tego samego zapytania. Jeśli kolejność ma znaczenie, trzeba ją wymusić klauzulą ORDER BY.
To ważniejsze, niż się wydaje. Jeżeli wynik wyszedł „przypadkiem" w dobrej kolejności bez ORDER BY, to jest właśnie przypadek – nie da się na nim polegać.
ORDER BY stawiamy na końcu zapytania, po WHERE. Kolejność jest logiczna: baza najpierw wybiera wiersze spełniające warunek, a dopiero potem układa to, co zostało.
Dwa kierunki sortowania. ASC (od ascending) porządkuje rosnąco – od najmniejszej wartości, a przy tekście od początku alfabetu. DESC (descending) odwrotnie: od największej, od końca alfabetu. Jeśli nie napiszesz nic, baza przyjmuje ASC – ale przy DESC słowo kluczowe jest obowiązkowe.
Sortowanie po kilku kolumnach. Po ORDER BY można wymienić kilka kolumn po przecinku. Druga kolumna rozstrzyga remisy w pierwszej, trzecia – remisy w drugiej i tak dalej. Zapis ORDER BY klasa, srednia DESC oznacza: najpierw poukładaj klasami rosnąco, a wewnątrz każdej klasy posortuj uczniów od najwyższej średniej. Zwróć uwagę, że DESC dotyczy tylko tej kolumny, przy której stoi – nie całej listy.
Sortować można też po aliasie zdefiniowanym w SELECT (AS) albo po wyrażeniu, którego wcale nie ma wśród wyświetlanych kolumn – baza liczy je od nowa na potrzeby porządkowania. Osobna pułapka czeka przy kolumnach tekstowych: jeśli liczba jest zapisana jako tekst, sortuje się alfabetycznie, znak po znaku, a nie jak liczba – patrz sekcja Typowe błędy.
Sortowanie działa na tym, co zostało po filtrowaniu klauzulą WHERE, i na kolumnach wybranych w zapytaniu SELECT. Puste wartości przy sortowaniu opisuje osobno hasło wartości NULL.
-- Bez ORDER BY kolejność wierszy jest nieokreślona SELECT nazwisko, srednia FROM uczniowie ORDER BY srednia DESC
| nazwisko | srednia |
|---|---|
| Wiśniewski | 5.10 |
| Kowalska | 4.75 |
| Dąbrowski | 4.10 |
| Zając | 3.90 |
| Nowak | 3.20 |
-- Sortowanie po dwóch kolumnach: klasa rosnąco, w niej średnia malejąco SELECT klasa, nazwisko, srednia FROM uczniowie ORDER BY klasa, srednia DESC
| klasa | nazwisko | srednia |
|---|---|---|
| 3A | Wiśniewski | 5.10 |
| 3A | Kowalska | 4.75 |
| 3B | Dąbrowski | 4.10 |
| 3B | Nowak | 3.20 |
| 3C | Zając | 3.90 |
-- ORDER BY zawsze po WHERE SELECT nazwisko, srednia FROM uczniowie WHERE srednia >= 4.00 ORDER BY nazwisko
| nazwisko | srednia |
|---|---|
| Dąbrowski | 4.10 |
| Kowalska | 4.75 |
| Wiśniewski | 5.10 |
-- Sortowanie po aliasie zdefiniowanym w SELECT SELECT nazwisko, srednia AS sr FROM uczniowie ORDER BY sr DESC
| nazwisko | sr |
|---|---|
| Wiśniewski | 5.10 |
| Kowalska | 4.75 |
| Dąbrowski | 4.10 |
| Zając | 3.90 |
| Nowak | 3.20 |
-- Pułapka: numer_w_dzienniku to kolumna tekstowa (10, 21, 33, 7, 9) – sortuje się alfabetycznie SELECT nazwisko, numer_w_dzienniku FROM uczniowie ORDER BY numer_w_dzienniku
| nazwisko | numer_w_dzienniku |
|---|---|
| Nowak | 10 |
| Dąbrowski | 21 |
| Wiśniewski | 33 |
| Zając | 7 |
| Kowalska | 9 |
ASC brane za DESC albo odwrotnie. SELECT nazwisko FROM uczniowie ORDER BY srednia sortuje rosnąco – Nowak (3.20) będzie pierwszy, Wiśniewski (5.10) ostatni. Kto oczekuje „od najlepszego", dostaje dokładnie odwrotną kolejność. Brakuje jednego słowa: ORDER BY srednia DESC.
DESC dopisane do całej listy zamiast do jednej kolumny. Zapis ORDER BY klasa DESC, srednia DESC sortuje malejąco obie kolumny – najpierw klasy 3C, 3B, 3A, a dopiero w ich obrębie średnią. Jeśli miał być tylko ranking wewnątrz klas idących rosnąco, trzeba napisać ORDER BY klasa, srednia DESC – DESC dotyczy tylko kolumny, przy której stoi.
Liczba w kolumnie tekstowej sortowana jak tekst. Gdy numer_w_dzienniku jest typu tekstowego, ORDER BY numer_w_dzienniku porównuje wartości znak po znaku: „1" jest mniejsze niż „9", więc „10" ląduje przed „9", a „21" przed „7". Wynik to 10, 21, 33, 7, 9 zamiast oczekiwanego 7, 9, 10, 21, 33. Naprawa to zmiana typu kolumny na liczbowy albo jawne rzutowanie w zapytaniu (w Accessie funkcją CLng()/CInt()).
ORDER BY wstawione przed WHERE. SELECT nazwisko FROM uczniowie ORDER BY nazwisko WHERE srednia >= 4 to błąd składni – baza zgłosi, że nie rozumie zapytania, i nie zwróci żadnego wyniku. Kolejność klauzul jest sztywna: SELECT → FROM → WHERE → ORDER BY.
Alias użyty w WHERE tak samo jak w ORDER BY. SELECT srednia AS sr FROM uczniowie WHERE sr >= 4 w wielu bazach kończy się błędem „nieznana kolumna sr" – w momencie liczenia WHERE alias jeszcze nie istnieje, powstaje dopiero przy budowaniu wyniku. W WHERE trzeba użyć pełnej nazwy kolumny (srednia >= 4), alias działa dopiero w ORDER BY i w samym SELECT.
Branie pierwszego wiersza za „najlepszy" bez ORDER BY. Zapytanie bez sortowania, z którego czyta się tylko pierwszy zwrócony wiersz, może w innym uruchomieniu zwrócić kogoś zupełnie innego – kolejność bez ORDER BY nie jest niczym gwarantowana. Wybieranie jednego, konkretnego rekordu (np. „ucznia z najwyższą średnią") łączy się z ograniczeniem liczby wierszy – tę technikę omawia hasło TOP / LIMIT.
Tabela uczniowie, na której działają wszystkie pytania poniżej:
| nazwisko | klasa | srednia |
|---|---|---|
| Kowalska | 3A | 4.75 |
| Nowak | 3B | 3.20 |
| Wiśniewski | 3A | 5.10 |
| Zając | 3C | 3.90 |
| Dąbrowski | 3B | 4.10 |
| Pytanie | Odpowiedź |
|---|---|
Ile wierszy zwróci SELECT nazwisko FROM uczniowie ORDER BY srednia? | |
Które nazwisko będzie pierwsze w wyniku SELECT nazwisko, srednia FROM uczniowie ORDER BY srednia DESC? | |
| Jakie słowo kluczowe trzeba dopisać po nazwie kolumny, żeby posortować ją malejąco? | |
Czyje nazwisko będzie w pierwszym wierszu wyniku ORDER BY srednia (bez DESC)? | |
W zapytaniu SELECT klasa, nazwisko, srednia FROM uczniowie ORDER BY klasa, srednia DESC która kolumna rozstrzyga kolejność uczniów w obrębie tej samej klasy? | |
| Które słowo baza przyjmuje domyślnie, gdy przy kolumnie w ORDER BY nie napiszemy ani ASC, ani DESC? | |
| SELECT nazwisko FROM uczniowie WHERE srednia 4 ORDER BY nazwisko | zwraca uczniów ze średnią co najmniej 4, posortowanych alfabetycznie |
| Ile nazwisk zwróci zapytanie z wiersza wyżej? |
Gdy w poleceniu pada słowo „malejąco" albo „od najlepszego", trzeba dopisać słowo kluczowe ; samo pominięcie kierunku oznacza sortowanie . Klauzula ORDER BY zawsze stoi , po klauzuli WHERE.
W większości baz tak – SELECT nazwisko FROM uczniowie ORDER BY srednia zadziała, mimo że średnia nie jest wyświetlana. Na maturze bezpieczniej jednak dopisać taką kolumnę do SELECT, bo widać wtedy, według czego wynik został ułożony.
Puste wartości baza grupuje razem – na początku albo na końcu wyniku, zależnie od konkretnego systemu. Nie ma tu jednej reguły wspólnej dla wszystkich baz, więc jeśli zadanie tego dotyka, warto to sprawdzić w programie, w którym pracujesz.
Nie. ORDER BY ustawia tylko kolejność wierszy w wyniku zapytania – dane w tabeli zostają dokładnie takie same. Kolejny SELECT bez ORDER BY może znowu zwrócić wiersze w zupełnie innej kolejności.
Kolejność między takimi wierszami jest nieokreślona – baza może je ułożyć w dowolny sposób względem siebie. Żeby to kontrolować, dopisuje się drugą kolumnę do ORDER BY, która rozstrzyga taki remis, np. ORDER BY srednia DESC, nazwisko.
Tak. Po ORDER BY można wpisać całe wyrażenie, np. ORDER BY srednia * 2 DESC – wynik będzie identyczny jak przy ORDER BY srednia DESC, bo pomnożenie każdej wartości przez tę samą liczbę nie zmienia ich wzajemnej kolejności.
Sortowanie to dodatkowa praca bazy, zwłaszcza przy dużej tabeli bez odpowiedniego indeksu – ale przy tabelach wielkości szkolnego dziennika ten koszt jest w praktyce niezauważalny. Na maturze wydajność zapytania nie jest oceniana, liczy się poprawna kolejność wyniku.
Da się napisać np. ORDER BY 2, czyli „sortuj po drugiej kolumnie z SELECT" – ale taki zapis jest kruchy, bo zmiana kolejności kolumn w SELECT po cichu zmienia sortowanie. Bezpieczniej pisać nazwę kolumny wprost.
Do tego hasła nie mamy jeszcze przypisanych pojedynczych zadań. Cały spis zadań maturalnych z tego działu jest tutaj:
Zagadnienia z tego samego obszaru matury – warto je powtórzyć razem: