Zliczanie, grupowanie, analizowanie: praktyczne zapytania w SQLiteStudio
Baza danych
Dysponujemy bazą danych SQLite3 zapisaną w pliku uczniowie2.db. Ćwiczenia wykonamy w programie SQLiteStudio, ale można do tego celu użyć wiersza poleceń bazy SQLite3. Informacje na temat tych narzędzi zawarte zostały w materiale Definiowanie schematu bazy danych w języku SQL, etap IIDefiniowanie schematu bazy danych w języku SQL, etap II. Zapytania można również wykonać za pomocą skryptu języka Python, który omówiono w materiale Instrukcje wyszukiwania w języku SQL, etap IIIInstrukcje wyszukiwania w języku SQL, etap III.
uczniowie2.db.Po uruchomieniu programu SQLiteStudio wybierz polecenie Bazy danych | Dodaj bazę danych i wskaż położenie pliku uczniowie2.db. Następnie połącz się z bazą, dwukrotnie klikając nazwę bazy w panelu Bazy danych.
Program SQLiteStudio ułatwia poznanie schematu bazy danych, udostępniając wszystkie informacje potrzebne do poznania tabel i łączących je relacji. Po dwukrotnym kliknięciu wybranej tabeli w panelu po lewej stronie, w zakładce Struktura zobaczymy nazwy i typy danych pól zawartych w tabeli.

Jeżeli klikniemy zakładkę DDL, zobaczymy polecenie SQL, które zostało użyte do utworzenia danej tabeli i ewentualnych powiązań.

Przeanalizuj schemat bazy, korzystając z informacji o tabelach widocznych na zakładkach Struktura i/lub DDL.
Grupowanie danych
Spróbujmy przeanalizować niektóre dane dotyczące uczniów zapisane w bazie danych.
Napiszmy kwerendę, która wyświetli liczbę uczniów mieszkających na tej samej ulicy.
Zacznijmy od zapytania zliczającego uczniów:
Dzięki funkcji COUNT() dowiemy się, że w bazie zapisano dane 414 uczniów.
Jeśli jednak chcemy zobaczyć, ilu uczniów mieszka na tej samej ulicy, powinniśmy pogrupować uczniów według nazw ulic i dopiero później zliczyć poszczególne grupy.
Na przykładzie tego zapytania widzimy, że do grupowania rekordów służy klauzula GROUP BY, po której podajemy nazwę pola. Ponadto w klauzuli SELECT uwzględniliśmy pole ulica, aby widzieć nazwy ulic, dla których zliczamy uczniów. Zapytanie pokazuje również, że klauzula AS jest opcjonalna, kiedy tworzymy aliasy pól. Klauzulę sortowania ORDER BY dodaliśmy dla czytelności wyników.
Początkowe zwrócone rekordy:
Grupowanie poprzedza operacje wykonywane przez funkcje agregujące (np. COUNT()), które mogą działać na wszystkich rekordach, na jednej grupie lub na wielu grupach.
Napiszmy kwerendę, która poda liczbę uczniów w poszczególnych klasach.
Uzyskanie takiej informacji wymaga sięgnięcia tylko do jednej tabeli, czyli uczniowie. W klauzuli SELECT wybieramy pole klasa, według którego grupujemy rekordy, oraz pole id_ucz, które zliczamy. W ten sposób otrzymamy tabelę z liczbą uczniów w poszczególnych klasach.
Początkowe zwrócone rekordy:
Napiszmy kwerendę, która wyświetli średnią ocen poszczególnych klas.
Problem sugeruje, że należy pogrupować uczniów według klas, a następnie policzyć średnią ich ocen. Źródłem kwerendy będzie zatem tabela uczniowie. Z niej wybieramy pole klasa, według którego będą grupowane rekordy. Drugą wymaganą tabelą będą oceny, z której dodajemy pole ocena i nakładamy na nie funkcję AVG() wyliczającą średnią. Zapis w języku SQL:
Do złączenia tabel użyliśmy klauzuli USING, która może zastąpić klauzulę JOIN ON, jeżeli pola tworzące relację mają taką samą nazwę. Wyświetlone średnie ocen można zaokrąglić przy użyciu funkcji ROUND(), której argumentami są średnia ocena wyliczona przez funkcję AVG() oraz precyzja. Początek kwerendy będzie miał wtedy postać:
Początkowe zwrócone rekordy:
Napiszmy zapytanie, które zwróci nazwę przedmiotu z najniższą średnią ocen.
Źródłem danych w zapytaniu będą tabele oceny i przedmioty. Dane trzeba pogrupować według pola nazwa z tabeli przedmioty. W klauzuli SELECT obok nazwy przedmiotu umieścimy funkcję AVG(), której przekażemy jako argument pole ocena. Rekordy uporządkujemy rosnąco według średnich ocen, a ich liczbę ograniczymy do jednego.
Kod SQL prezentuje się następująco:
Operacja grupowania nie wyklucza sortowania w klauzuli ORDER BY ani ograniczania liczby zwracanych rekordów w klauzuli LIMIT.
Wynik kwerendy:
Sortowanie następuje po grupowaniu. Tym samym w klauzuli sortowania można podać pola, według których następuje grupowanie, lub pola, na których wykonywana jest funkcja agregująca.
Użycie podzapytań
Napiszmy zapytanie, które zwróci średnie ocen z poszczególnych przedmiotów podanej klasy, np. 1a.
Rozwiązanie zaczniemy od skonstruowania zapytania, które pobierze wszystkie oceny uczniów z podanej klasy. W wynikach kwerendy chcemy mieć nazwę klasy, nazwę przedmiotu oraz oceny, dlatego w klauzuli SELECT umieszczamy pola klasa, nazwa i ocena. Każde z tych pól jest w innej tabeli, warunki złączenia definiujemy za pomocą pól id_prz oraz id_ucz, które tworzą relację, w klauzuli WHERE. Dodajemy również warunek pozwalający wybrać rekordy klasy 1a. Kod SQL:
Wynikiem kwerendy będzie tabela ocen podanej klasy. Początkowe rekordy:
Teraz zaprojektujemy końcową kwerendę, która pogrupuje oceny według nazw przedmiotów, obliczy średnią dla każdej grupy i wyświetli nazwy przedmiotów oraz średnie ocen. Poprzednie zapytanie umieścimy w klauzuli FROM jako źródło końcowej kwerendy.
Kod SQL przyjmie postać:
Kwerendy wykorzystywane wewnątrz innej kwerendy nazywamy podzapytaniami. Po podzapytaniach nie stawiamy średników, są one wykonywane w pierwszej kolejności.
Dodaj do ostatniej kwerendy sortowanie malejące wyników według średniej ocen z przedmiotów.
Kwerenda parametryczna
Ostatnia kwerenda byłaby o wiele bardziej użyteczna, gdyby pozwalała na podawanie nazwy klasy przed wykonaniem. Taką możliwość łatwo uzyskać, przekształcając zapytanie w kwerendę parametrycznąkwerendę parametryczną. Wystarczy zamiast nazwy klasy wpisać znak zapytania. Zapytanie przyjmie następującą postać:
![Okno Parametry zapytania w programie SQLiteStudio. Tytuł okna Parametry zapytania. Proszę podać wartości dla parametrów zapytania. [1]? opcja do wyboru Wartość null. Poniżej dwie zakładki: Liczba oraz Tekst. Wyświetlono Tekst. W polu wpisani 1a. Poniżej dwa przyciski Abort, OK.](https://static.zpe.gov.pl/portal/f/res-minimized/RzIH6SAyF2Ubk/1690815783/1yRD5WYquOwU0c8num9MUIzyp2guimAx.png)
Parametry zapytania w programie SQLiteStudio.Podane zapytanie wykona się w programie SQLiteStudio, który wyświetli okno dialogowe pozwalające podać odpowiednią wartość. Nazwę klasy należy wprowadzić w zakładce Tekst i kliknąć OK.
W wierszu poleceń bazy SQLite lub w zapytaniach wykonywanych przy użyciu skryptu Pythona kwerenda nie zadziała.
Filtrowanie grup rekordów
Napiszmy zapytanie, które zwróci nazwy i średnią ocen klas, jeżeli średnia ocen będzie większa od 3.
Problem postawiony w zadaniu podobny jest do zadania, w którym chcieliśmy otrzymać średnie oceny wszystkich klas. Rozwiązanie opiera się więc na poprzedniej kwerendzie:
Nowością jest klauzula HAVING, która może występować tylko po klauzuli grupującej. Używamy jej wtedy, kiedy nakładamy jakieś warunki na grupy rekordów.
Zwrócone rekordy:
Warunki z klauzuli WHERE nakładane są przed grupowaniem. Tym samym odfiltrowane rekordy nie są brane pod uwagę przy grupowaniu. W powyższym przykładzie moglibyśmy wykluczyć z otrzymanego zestawienia, np. klasy o profilu matematycznym. Na potrzeby przykładu załóżmy, że są to wszystkie klasy z literą „a” w nazwie:
Zwrócone rekordy:
Słownik
tworzenie zbiorów rekordów na podstawie takich samych wartości z podanej kolumny; grupowanie zazwyczaj poprzedza zastosowanie funkcji agregującej, która przeprowadza obliczenia na grupie rekordów
kwerenda, w której wartości w wyrażeniach warunkowych są parametrem podawanym przed wykonaniem zapytania; parametry oznaczane są znakami zapytania
