Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

Wydział Mechaniczny

(opcjonalnie)
Katedra Konstrukcji Badań Maszyn i Pojazdów

Bazy danych 1
Dr inż. Paweł Maślak

pawel.maslak@pwr.edu.pl

Laboratorium 5: Podstawy języka SQL, część 2,

1. Cel ćwiczenia Poruszane zagadnienia: polecenie SELECT, funkcje agregujące SUM, MIN,
MAX, AVG, COUNT, klauzula GROUP BY, klauzula HAVING
2. Warunkiem uzyskania w ćwiczeniu takich jak poniżej wyników jest praca na
demonstracyjnym schemacie relacyjnym, o którym mowa jest w jednym z poprzednich
ćwiczeń. Dlatego też należy upewnić się, że odpowiedni skrypt wykonał się bezbłędnie
(poprawnie utworzyły się wszystkie tabele oraz załadowały się wszystkie dane). Dla
pewności warto przed rozpoczęciem ćwiczenia po prostu utworzyć schemat od nowa,
nawet jeżeli wydaje ci się, że ten, który masz aktualnie zainstalowany jest poprawny.
W celu sprawdzenia jakie tabele są dostępne to w bazie lab proszę wpisać:
MariaDB [lab]> show tables;
+---------------+
| Tables_in_lab |
+---------------+
| customer |
| dept |
| emp |
| inventory |
| item |
| ord |
| product |
| region |
| title |
| warehouse |
+---------------+
10 rows in set (0.033 sec)
Klauzula GROUP BY

Gdy używamy funkcji grupującej GROUP BY musi ona wystąpić po klauzuli WHERE. W klauzuli
SELECT mogą wówczas wystąpić tylko:

• funkcje agregujące (np. SUM, MIN, MAX, AVG, COUNT),


• nazwy kolumn występujące w funkcji grupującej GROUP BY,
• wyrażenia stałe.

Uwaga: MySQL zmienia zdefiniowaną normą SQL funkcjonalność klauzuli GROUP BY. Można
mianowicie w klauzuli SELECT wpisywać kolumny, które nie są wymienione w GROUP BY. Może
to jednak prowadzić do „dziwnych” (trudnych w interpretacji i mylących zarazem) wyników.
Porównajmy:

>SELECT dept_id, SUM(salary), ‘wyrazenie stale’ FROM emp GROUP BY dept_id;


>SELECT first_name, dept_id, SUM(salary) FROM emp GROUP BY dept_id;

Jak interpretować pierwszą kolumnę w drugim rozwiazaniu?

Przykład:

SELECT
emp.title,
SUM(emp.salary),
COUNT(*)
FROM
emp
GROUP BY
emp.title;

+----------------------+-----------------+----------+
| emp.title | SUM(emp.salary) | COUNT(*) |
+----------------------+-----------------+----------+
| President | 2500.00 | 1 |
| Sales Representative | 7380.00 | 5 |
| Stock Clerk | 9490.00 | 10 |
| VP, Administration | 1550.00 | 1 |
| VP, Finance | 1450.00 | 1 |
| VP, Operations | 1450.00 | 1 |
| VP, Sales | 1400.00 | 1 |
| Warehouse Manager | 6157.00 | 5 |
+----------------------+-----------------+----------+
8 rows in set (0.001 sec)
W powyższym przykładzie wyświetliliśmy sumę zarobków wszystkich pracowników pracujących na
poszczególnych stanowiskach. Dodatkowo wyświetliliśmy informację o tym, ilu pracowników pracuje
na każdym ze stanowisk.

2
Przykład:

MariaDB [lab]> SELECT emp.title, COUNT(*) FROM emp GROUP BY emp.title DESC;

+----------------------+----------+
| emp.title | COUNT(*) |
+----------------------+----------+
| Warehouse Manager | 5 |
| VP, Sales | 1 |
| VP, Operations | 1 |
| VP, Finance | 1 |
| VP, Administration | 1 |
| Stock Clerk | 10 |
| Sales Representative | 5 |
| President | 1 |
+----------------------+----------+
8 rows in set (0.001 sec)

Kolejną zmianą w stosunku do standardowego zachowania się GROUP BY jest możliwość sortowania
kolejności grup. Domyślna kolejność jest rosnąca. W powyższym przykładzie zmieniliśmy kierunek
sortowania na malejący (od ’Z’ do ’A’).

Przykład:

MariaDB [lab]> SELECT title, SUM(salary) FROM emp WHERE SUM(salary) > 2000
GROUP BY title;
ERROR 1111 (HY000): Invalid use of group function

W tym przykładzie (niestety błędnym!) staraliśmy się wyświetlić tylko sumę zarobków pracowników
z tych stanowisk, gdzie ta suma jest większa niż 2000. Okazuje się, że aby wykonać takie zadanie
należy użyć klauzuli HAVING

Klauzula HAVING

MariaDB [lab]> SELECT title, SUM(salary) FROM emp GROUP BY title HAVING
SUM(salary) > 2000;
+----------------------+-------------+
| title | SUM(salary) |
+----------------------+-------------+
| President | 2500.00 |
| Sales Representative | 7380.00 |
| Stock Clerk | 9490.00 |
| Warehouse Manager | 6157.00 |
+----------------------+-------------+
4 rows in set (0.021 sec)

Zasada działania klauzuli HAVING jest następująca: podczas tworzenia każdej grupy (za
pomocą GROUP BY) obliczana jest suma zarobków (SUM(salary)) dla tej grupy. Kiedy
warunek logiczny sprawdzany z pomocą klauzuli HAVING jest spełniony, taka grupa jest
uwzględniana w wyniku i wyświetlana.

3
Zadanie 1

Wyświetlić maksymalne, minimalne oraz średnie zarobki wszystkich pracowników. Użyć funkcji

SUM, AVG, MIN, MAX oraz COUNT. Jako wynik powinniśmy otrzymać:

+--------+---------+-------------+----------+-------------------+
| Min | Max | Srednie | Suma | Liczba prac |
+--------+---------+-------------+----------+-------------------+
| 750.00 | 2500.00 | 1255.080000 | 31377.00 | 25 |
+--------+---------+-------------+----------+-------------------+
1 row in set (0.143 sec)

Zadanie 2

Wyświetlić informację ilu pracowników zarabia w przedziale od 1000 do 2000 (zbiór domknięty).

Jako wynik powinniśmy otrzymać:

+-----------------+
| od 1000 do 2000 |
+-----------------+
| 17 |
+-----------------+
1 row in set (0.021 sec)

Zadanie 3

Wyświetlić informację o kosztach płacowych w poszczególnych wydziałach (użyć klauzuli GROUP


BY). Jako wynik powinniśmy otrzymać:

+--------------+---------------+--------------+
| numer dzialu | Suma zarobkow | Liczba prac. |
+--------------+---------------+--------------+
| 10 | 1450.00 | 1 |
| 31 | 2800.00 | 2 |
| 32 | 1490.00 | 1 |
| 33 | 1515.00 | 1 |
| 34 | 2320.00 | 2 |
| 35 | 1450.00 | 1 |
| 41 | 4990.00 | 4 |
| 42 | 3245.00 | 3 |
| 43 | 2700.00 | 3 |
| 44 | 2100.00 | 2 |
| 45 | 3267.00 | 3 |
| 50 | 4050.00 | 2 |
+--------------+---------------+--------------+
12 rows in set (0.018 sec)

4
Zadanie 4

Wyświetlić informację o kosztach płacowych w poszczególnych wydziałach, tym razem ograniczając


się tylko do działów o numerach 41, 42 oraz 43 (użyć klauzuli HAVING). Jako wynik powinniśmy
otrzymać:

+--------------+---------------+--------------+
| numer dzialu | Suma zarobkow | Liczba prac. |
+--------------+---------------+--------------+
| 41 | 4990.00 | 4 |
| 42 | 3245.00 | 3 |
| 43 | 2700.00 | 3 |
+--------------+---------------+--------------+
3 rows in set (0.001 sec)

Zadanie 5 - tutaj pojawia się złączanie tabel o czym na kolejnych zajęciach

Wyświetlić informację o kosztach płacowych w poszczególnych działach. Jako wynik powinniśmy


otrzymać:

SELECT
dept.region_id AS `Numer regionu`,
dept.id AS `Numer dzialu`,
dept.name AS `Nazwa dzialu`,
SUM(emp.salary) AS `Suma zarobkow`,
COUNT(emp.id) AS `Liczba pracownikow`
FROM dept
JOIN emp ON(dept.id = emp.dept_id)
GROUP BY
dept.region_id,
dept.id,
dept.name
ORDER BY
1, 5
DESC;

+---------------+--------------+----------------+---------------+--------------------+
| Numer regionu | Numer działu | Nazwa działu | Suma zarobków | Liczba pracowników |
+---------------+--------------+----------------+---------------+--------------------+
| 1 | 41 | Operations | 4990.00 | 4 |
| 1 | 31 | Sales | 2800.00 | 2 |
| 1 | 50 | Administration | 4050.00 | 2 |
| 1 | 10 | Finance | 1450.00 | 1 |
| 2 | 42 | Operations | 3245.00 | 3 |
| 2 | 32 | Sales | 1490.00 | 1 |
| 3 | 43 | Operations | 2700.00 | 3 |
| 3 | 33 | Sales | 1515.00 | 1 |
| 4 | 34 | Sales | 2320.00 | 2 |
| 4 | 44 | Operations | 2100.00 | 2 |
| 5 | 45 | Operations | 3267.00 | 3 |
| 5 | 35 | Sales | 1450.00 | 1 |
+---------------+--------------+----------------+---------------+--------------------+
12 rows in set (0.001 sec)

5
Zadanie 6

Wyświetlić informację o kosztach płacowych w poszczególnych regionach. Zwrócić uwagę na to, że


w tabeli dept nazwy działów dublują się (różne są natomiast region_id). Zgodność otrzymanego
wyniku łatwo jest sprawdzić poprzez zsumowanie odpowiednich (jakich?) liczb uzyskanych w
poprzednim ćwiczeniu (zakładając oczywiście, że tam otrzymano poprawny wynik). Jako wynik
powinniśmy otrzymać:

+----+----------------------+---------------+--------------------+
| id | name | Suma zarobków | Liczba pracowników |
+----+----------------------+---------------+--------------------+
| 1 | North America | 13290.00 | 9 |
| 2 | South America | 4735.00 | 4 |
| 3 | Africa / Middle East | 4215.00 | 4 |
| 4 | Asia | 4420.00 | 4 |
| 5 | Europe | 4717.00 | 4 |
+----+----------------------+---------------+--------------------+
5 rows in set (0.01 sec)

Zadanie 7

Sprawdzić spójność danych w tabelach ord oraz item. Dane będziemy uważali za spójne, gdy suma, na
którą opiewa zamówienie (wartość w kolumnie total) dla każdego zamówienia będzie dokładnie taka
sama jak wartość zamówienia wyliczona jako suma iloczynów price * quantity w tabeli item
(uzasadnij dlaczego). Jako wynik powinniśmy otrzymać:

+------------+------------------------+---------+
| TOTAL, ord | PRICE * QUANTITY, item | Różnica |
+------------+------------------------+---------+
| 377.00 | 377.00 | 0.00 |
| 550.00 | 550.00 | 0.00 |
| 595.00 | 595.00 | 0.00 |
| 1539.13 | 1539.13 | 0.00 |
| 2722.24 | 2722.24 | 0.00 |
| 2770.00 | 2770.00 | 0.00 |
| 7707.00 | 7707.00 | 0.00 |
| 8056.60 | 8056.60 | 0.00 |
| 8335.00 | 8335.00 | 0.00 |
| 15634.00 | 15634.00 | 0.00 |
| 32430.00 | 32430.00 | 0.00 |
| 84000.00 | 84000.00 | 0.00 |
| 142171.00 | 142171.00 | 0.00 |
| 149570.00 | 149570.00 | 0.00 |
| 601100.00 | 601100.00 | 0.00 |
| 1020935.00 | 1020935.00 | 0.00 |
+------------+------------------------+---------+
16 rows in set (0.06 sec)

6
Zadanie 8

Wyświetlić prosty raport o klientach. Zwrócić uwagę, że wynik posortowany jest wg. Ilości klientów
w danym regionie (użyć funkcji konkatenacji CONCAT). Jako wynik powinniśmy trzymać:

+-----------------------------------------------------+
| INFO |
+-----------------------------------------------------+
| Z regionu NORTH AMERICA pochodzi 4 klientów. |
| Z regionu EUROPE pochodzi 4 klientów. |
| Z regionu ASIA pochodzi 3 klientów. |
| Z regionu AFRICA / MIDDLE EAST pochodzi 2 klientów. |
| Z regionu SOUTH AMERICA pochodzi 2 klientów. |
+-----------------------------------------------------+
5 rows in set (0.00 sec)

You might also like