■3ZU 5. JĘZYK BAZ DANYCH SQ1.
Zauważmy, że klauzula SELECT w przykładzie 5.24 zawiera dwa rodzaje termów:
1. Agregaty; argumentem operatora są tu atrybuty lub wyrażenia zawierające atrybuty. Wartości tych termów są wyliczane dla poszczególnych grup.
2. Same atrybuty, takie jak w tym przykładzie nazwaStudia, które występują w klauzuli grouf by. 1 tylko atrybuty występujące wr klauzuli GROUP BY mogą wystąpić również w' klauzuli SELECT poza agregatami.
W zasadzie zapytania grupujące GROUP BY w klauzuli SELECT zawierają zarówno agregaty, jak i atrybuty grupujące, jednak technicznie nie wymaga się, aby oba te typy występowały jednocześnie. Na przykład poprawne jest również następujące zapytanie;
SELECT nazwaStudia
FROM Film
GROUP BY nazwaStudia
W jego wyniku krotki relacji Film zostaną pogrupowane według nazw- studiów, a potem te nazwy zostaną wydrukowane, każda z nich tylko jeden raz, bez względu na to, ile krotek relacji Filn zawiera daną nazwę. Powyższe zapylanie daje laki sam wynik jak zapytanie następujące:
SELECT DISTINCT nazwaStudia
FROM Film
Klauzulę GROUP BY można stosować również w zapytaniach dotyczących więcej niż tylko jednej relacji. Wówczas ciąg przetwarzania zapytania składa się z następujących kroków--;
1. Obliczenie relacji R, która pow\staje z klauzul FROM i WHERE, tzn. przez utworzenie iloczynu kartezjańskiego z relacji klauzuli FROM i wybranie z iloczynu tych krotek, które spełniają warunek where.
2. Pogrupowanie krotek relacji R według atrybutów zawartych w klauzuli GROUP by.
3. Do wyniku wpisuje się wartości atrybutów i agregatów zawartych w klauzuli select, tak jakby zapytanie dotyczyło relacji R.
PRZYKŁAD 5.25
Załóżmy, że trzeba wydrukować tabelę zawierającą długość filmów, które powstały w studiach danego producenta. Wówczas dane trzeba pobierać z dwóch relacji:
Film(tytuł, rok, długość, czyKolor, nazwaStudia, producentCf)
FilmDyr(nazwisko, adres, cert#, cenaSieci)
Najpierw tworzymy złączenie teta tych dwóch relacji, gdzie warunkiem złączenia jest równość numerów certyfikatów. Otrzymujemy w ten sposób relację, w której każdy film danego producenta występuje w parze z krotką opisującą tego producenta. Teraz można pogrupować krotki tej relacji według nazwiska producenta. Na koniec można podsumować długości filmów w poszczególnych grupach. Opisane zapytanie zostało przedstawione na rys. 5.10.
□
1) SELECT nazwisko, SUM(długość)
2) FROM FilmDyr, Film
3) WHERE producentCf cert#
4) GROUP BY nazwisko;
RYSUNEK 5. U)
Obliczenie długości filmów poszczególnych producentów
Załóżmy teraz, że do tabeli zdefiniowanej w przykładzie 5.25 nie chcemy zapisać wszystkich producentów. Możemy to osiągnąć, jeśli ograniczymy zestaw krotek, zanim zaczną być grupowane. Na przykład, jeśli interesuje nas długość filmów wyprodukowanych przez producentów, których sieci są warte co najmniej 10 000 000 $, to można zmienić w tym celu wiersz 3) z rys. 5.10 w sposób następujący:
3) WHERE producentCf cert# AND cenaSieci >=
10 000 000
Jednakże może się zdarzyć, że warunek wyboru może dotyczyć całej grupy według jakiejś wartości zagregowanej. Wówczas po klauzuli WHERE należy umieścić klauzulę HAVING wraz z warunkiem mówiącym, o jakie grupy chodzi.
PRZYKŁAD 5.26
Przypuśćmy, że chcemy uzyskać sumaryczne wartości długości filmów tylko tych producentów, którzy nakręcili co najmniej jeden film przed 1930 rokiem. Można to osiągnąć, jeśli do zapytania na rys. 5.10 dołączymy następującą klauzulę:
HAVING MIN(rok) < 1930