488 8. ZORIENTOWANE OBIEKTOWO JĘZYKI ZAPYTAŃ
Korzystamy tutaj z podzapytania po to. by wyodrębnić składowe długości filmów. W wyniku tego podzapytania powstaje wielozbiór z długościami wszystkich filmów i po zastosowaniu do niego operatora AVG otrzymujemy w łaściwy wynik.
□
Klauzula GROUP BY. znana z $QL, rozszerza się w bardzo ciekawy sposób w języku OQL. Składa się ona z następujących elementów.
2. Lista atrybutów grupujących, oddzielanych przecinkami. Każdy z nich składa się z kolei z:
a) nazwy- pola,
b) przecinka oraz
c) wyrażenia.
A w ięc postać klauzuli GROUP BY można przedstawić następująco:
GROUP BY f:euf2:e2,
Klauzulę GROUP BY umieszcza się na końcu zapytania sclcct-from--where. Wyrażenie:
e2,
może zawierać zmienne wymienione w klauzuli FROM. Aby ułatw ić objaśnienie działania GROUP BY, ograniczymy się do dość popularnego przypadku, gdy w klauzuli from występuje tylko jedna zmienna x. Zmienna x przebiega pewną kolekcję C. Dla każdego elementu z C. powiedzmy /, który spełnia warunek klauzuli where, oblicza się wartości wszystkich wyrażeń klauzuli GROUP BY i w ten sposób otrzymujemy wartości e\(i), e2(7), c„(i). Ta lista
w-artości tworzy grupę, do której należy wartość /.
Wartość klauzuli GROUP by jest zbiorem struktur. Elementy tego zbioru mają następującą postać:
Struct(/i:vi?/2:v2, partition: P)
Pierwsze n pól określa grupy. To znaczy vb v2, ..., v„ są wartościami powstałymi w wyniku obliczenia wyrażeń <?,(/'), e2(i),..., en{i) dla co najmniej jednej wartości i z kolekcji C. która spełnia warunek WHF.RE.
Ostatnie pole jest nazwane partition. Intuicyjnie jego wrartość P jest równa pewnej wartości i, która należy do tej grupy. A mów iąc dokładniej, P jest wielozbiorem złożonym ze struktur o następującej postaci:
Struct(x:i)
gdzie x jest zmienną klauzuli from.
Klauzula SELECT wyrażenia select-from-where, w którym występuje klauzula GROUP BY, może zawierać tylko te pola, które są. elementami GROUP BY, a więc fufi, oraz partition. Poprzez partition można odwoły
wać się do zmiennej która występuje w strukturach będących elementami wielozbioru 1\ który z kolei jest wartością pola partition. Krótko mówiąc, można odwoływać się do zmiennej x, która występuje w klauzuli "ROM, ale można to zrobić tylko poprzez operator agregowania, który jest zastosowany do wielozbioru P.
PRZYKŁAD 8.13
Utwórzmy tabelę zawierającą całkowitą długość wszystkich filmów wyprodukowanych w poszczególnych latach przez poszczególne studia. A zatem chcemy wyrazić w języku OQL utworzenie wielozbioru struktur - każda struktura ma trzy składowe: studio, rok oraz całkowitą długość wyprodukowanych w tym czasie filmów' w tym studio. Zapytanie zostało przedstawione na rys. 8.7.
SELECT std, r, sumaDługości: SUM(SELECT p.m.długość
erom partition p)
FROM Filmy n
GROUP BY std: ra. studio, r: m.rok RYSUNEK 8.7
Grupowanie filmów według studia i roku
Zacznijmy od omówienia działania klauzuli FROM w tym zapytaniu. Widzimy, że zmienna m przebiega zbiór obiektów klasy FiJrr. A więc m odgrywa rolę x z naszego ogólnego opisu. W klauzuli GROUP BY występują dwa pola std i r, które odpowiadają kolejno wyrażeniom: m. sr.uciic oraz m. rok.
Na przykład film Pretty Wonum został wyprodukowany w studiu Disneya w 1990 roku. Jeśli m oznacza ten film, to m.studio ma wartość „Disney", a m.rok ma wartość 1990. A więc jednym z elementów zbioru tworzonego w klauzuli GROUP by jest struktura następująca:
Slruct(stc:„Disney", r:1390, partition:P)
gdzie P jest zbiorem struktur. Należy do niego między innymi następująca struktura:
Struci (m:/Wp*)
gdzie Wp* oznacza obiekt opisujący film Pretty Woman. W P występują struktury o jednej składowej oznaczającej film wyprodukowany w studiu Disneya w roku 1990.