sobota, 6 listopada 2010

Kurs Oracle SQL. Sortowanie

ORDER BY – sortowanie


Klauzula order by służy do sortowania wyników zapytania. Przy zapytaniu bez użycia ORDER BY którego efektem jest wyświetlenie nazw departamentów, kolejność sortowania wydaje się być przypadkowa. W rzeczywistości jest to sortowane wg klucza głównego, w tym przypadku kolumny department_id.



Możemy jednak wyświetlić dane posortowane wg wybranej kolumny. W tym celu dodajemy do zapytania klauzulę order by określającą kolumnę wg której dane mają być sortowane. W poniższym przykładzie dane sortowane są wg kolejności alfabetycznej treści kolumny department_name.
Klauzula ta ma zastosowanie nie tylko do wartości tekstowych, ale również do kolumn liczbowych, zawierających daty i wartości logiczne. Jeśli nie istnieje potrzeba stosowania sortowania, nie powinniśmy z niej korzystać ponieważ powoduje dodatkowe niepotrzebne obciążenie serwera bazy danych.





Sortować możemy po więcej niż jednej kolumnie. Wystarczy po ORDER BY wymienić kolejne kolumny po których wynik ma zostać posortowany. Zamiast nazw kolumn możemy użyć cyfry które określają kolejność wymienienia tych 1kolumn po SELECT.



Możemy więc posortować id i nazwę departamentu najpierw według id a następnie wg nazwy na dwa sposoby:
select location_id, department_name from departments order by location_id, department_name;



lub



select location_id, department_name from departments order by 1,2 ;


ASC i DESC

Sposób sortowania możemy określić poprzez zastosowanie słów ASC oraz DESC ustanawiających kierunek sortowania. Domyślnie dla baz Oracle stosowane jest sortowanie ASC czyli od wartości najmniejszej do największej. Dzieje się tak nawet kiedy tego nie określimy.

Zapytanie
select department_name from departments order by department_name ;

jest równoznaczne z :

select department_name from departments order by department_name asc;



Sortowanie możemy odwrócić tak, by wartości były malejące przy pomocy słowa DESC:






W tym przypadku sortowanie odbywa się w odwrotnym kierunku.






NULLS FIRST I NULLS LAST


Domyślnie wartości null pojawiają się w przypadku sortowania rosnącego na końcu sortowania rosnącego (czyli domyślnego) . Aby to zmienić musimy po nazwie sortowanej kolumny dodać klauzulę NULLS FIRST.
Jeśli sortujemy malejąco, wartości null pojawią się domyślnie na początku. Aby to zmienić musimy zastosować NULLS LAST.

select job_id from jobs order by job_id nulls last;





Ćwiczenia




1. Wyświetl całą zawartość tabeli departments.
2. Wyświetl tylko nazwy departamentów z tabeli departments.
3. Wyświetl tylko zawartość kolumn state_province i city z tabeli locations
w taki sposób by tam gdzie state_province jest puste w miejsce bez wartości
został wstawiony tekst "brak" a nazwa kolumny w wyniku była "lokalizacja"
4. Wyświetl bez powtórzeń id wszystkich departamentów z tabeli employees
i posortuj je malejąco.


Ten temat omawiam na poniższych szkoleniach:
Podstawy Oracle SQL
Podstawy SQL i PL/SQL
Możesz w nich uczestniczyć, a jako czytelnik tego bloga otrzymasz 10% zniżki - poinformuj o tym fakcie konsultanta.

8 komentarzy:

  1. NULLS LAST, NULLS FIRST to interesujące przełączniki, chociaż lepszym rozwiązaniem w wielu przypadkach może być użycie funkcji NVL. W szczególności, jeśli NULL jest wyświetlane w aplikacji klienckiej jako pusta komorka w tabeli, można zastąpić NULL znaczącą wartością, np. 0 w polach numerycznych a "N/A" lub "(brak)" w polach tekstowych.

    OdpowiedzUsuń
  2. Te dwie sprawy służą zgoła czemu innemu. Nulls first i last służą tylko do sortowania np. przy maści różnej outer joinach. NVL to nie tylko estetyka, czasem się go stosuje by dalej przeliczać wartości z kolumny liczbowej, a do obliczeń musimy się pozbyć nulli.

    OdpowiedzUsuń
  3. Zgadza się, służą czemu innemu. Ale podałeś przykład liczenia: w zależności od ustawień sesji, od implementacji języka SQL itp., możemy zostać zaskoczeni wynikami. NULL może być potraktowane w ten sposób, że np. dodanie NULL do innych wartości da w wyniku NULL. Ale może być też pominięte.

    Żeby uniknąć konieczności pamiętania lub sprawdzania, co serwer zrobi z NULL, lepiej coś za NULL podstawić i uniezależnić się.

    Tyle wiem z ogólnej wiedzy o bazach, nie wiem, jak ma Oracle. A dodałem komentarz ze względu na czytelników, którzy są początkujący w ogóle, a nie tylko względem Oracle.

    OdpowiedzUsuń
  4. Mam mały problem z ćwiczeniem 4.
    Wpisuję komendę

    select distinct department_id from employees

    i otrzymuję jedną wartość (null) przez co funkcja 'order by' nie działa

    Jakieś pomysły czemu tak jest?

    OdpowiedzUsuń
  5. Spróbuj pobrać wszystko '*' z tabeli employees. Potem dodawaj kolejno argumenty polecenia select.
    Znajdziesz, co jest nie tak.
    U mnie polecenie:

    SELECT distinct department_id FROM employees order by 1;

    zadziałało bez niespodzianek.

    OdpowiedzUsuń
  6. czy zadanie 3 da się zrobić za pomocą jednej komendy? mi się nie udało. Osiągnołem jedynie połowiczny sukces używając komendy:

    select city, state_province as lokalizacja, nvl(state_province, 'brak') from locations;
    ale wtedy tworzą mi się trzy kolumny, gdzie jedna nazywa się 'lokalizacja' ale z purtymi wartościami. Kolejna natomiast kolumna ma już zastąpione puste miejsca słowem 'brak' natomiast nosi nazwę nvl(state_province,'brak')

    OdpowiedzUsuń
  7. @Grzegorz select nvl(state_province, 'brak') as "lokalizacja", city from locations;

    OdpowiedzUsuń
  8. Rozwiązanie:

    1. Select * from departments
    2. Select department_name from departments
    3. Select nvl(state_province, 'brak') lokalizacja, city from locations
    4. Select distinct department_id from employees order by 1 desc

    OdpowiedzUsuń