Podzapytanie zwraca tabelę
I wreszcie, trzecią opcją jest zwrócenie przez podzapytanie całej tabeli. Jest to najczęstsza opcja.
Bardzo często zdarzają się sytuacje, kiedy chcemy trochę podrasować określoną tabelę. I dopiero wtedy połącz (za pomocą operatora JOIN ON) poprawioną tabelę z inną.
Zacznijmy od najprostszego przypadku, w którym połączyliśmy dwie tabele za pomocą JOIN:
SELECT * FROM employee e JOIN task t ON e.id = t.emploee_id
I jak zapewne pamiętasz, w tabeli zadań znajdują się zadania , które nie są nikomu przypisane: id_pracownika to NULL .
Wygenerujmy poprawioną tabelę , w której przypisujemy wszystkie wiszące zadania dyrektorowi (jego ID = 4).
W tym celu używamy funkcji IFNULL() :
SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline FROM task
I wynik tego zapytania:
ID | dowód pracownika | nazwa | termin ostateczny |
---|---|---|---|
1 | 1 | Napraw błąd w interfejsie użytkownika | 2022-06-01 |
2 | 2 | Napraw błąd w backendzie | 2022-06-15 |
3 | 5 | Kup kawę | 2022-07-01 |
4 | 5 | Kup kawę | 2022-08-01 |
5 | 5 | Kup kawę | 2022-09-01 |
6 | 4 | Posprzątaj biuro | (ZERO) |
7 | 4 | Ciesz się życiem | (ZERO) |
8 | 6 | Ciesz się życiem | (ZERO) |
Poprawiona komórka jest zaznaczona na czerwono.
Podstawmy teraz naszą poprawioną tabelę do zapytania:
SELECT * FROM employee e JOIN task t ON e.id = t.emploee_id
Zamiast tabeli zadań .
Takie żądanie wyglądałoby mniej więcej tak:
SELECT * FROM employee e JOIN (
SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline
FROM task
) t ON e.id = t.emploee_id
Zamiast słowa task napisaliśmy nawiasy i umieściliśmy w nich treść żądania.
Nawiasem mówiąc, alias t (alias) dla zagnieżdżonego zapytania był bardzo przydatny. Zagnieżdżone zapytanie, w przeciwieństwie do tabeli, nie ma własnej nazwy, więc alias jest bardzo nie na miejscu.
A oto wynik takiego zapytania:
ID | nazwa | zawód | wynagrodzenie | wiek | data_dołączenia | ID | dowód pracownika | nazwa |
---|---|---|---|---|---|---|---|---|
1 | Iwanow Iwan | Programista | 100000 | 25 | 2012-06-30 | 1 | 1 | Napraw błąd w interfejsie użytkownika |
2 | Pietrow Pietr | Programista | 80000 | 23 | 2013-08-12 | 2 | 2 | Napraw błąd w backendzie |
4 | Rabinowicz Mojsza | Dyrektor | 200000 | 35 | 2015-05-12 | 6 | 4 | Posprzątaj biuro |
4 | Rabinowicz Mojsza | Dyrektor | 200000 | 35 | 2015-05-12 | 7 | 4 | Ciesz się życiem |
5 | Kirienko Anastazja | Kierownik biura | 40000 | 25 | 2015-10-10 | 4 | 5 | Kup kawę |
5 | Kirienko Anastazja | Kierownik biura | 40000 | 25 | 2015-10-10 | 5 | 5 | Kup kawę |
5 | Kirienko Anastazja | Kierownik biura | 40000 | 25 | 2015-10-10 | 3 | 5 | Kup kawę |
6 | Vaska | kot | 1000 | 3 | 2018-11-11 | 8 | 6 | Ciesz się życiem |
Nasz dyrektor ma za zadanie „posprzątać biuro”, myślę, że szybko znajdzie kogoś, komu to zleci :) Za pomocą operatora WITH
Nawiasem mówiąc, począwszy od wersji 8 MySQL, nie musisz już umieszczać wszystkich swoich podzapytań bezpośrednio w końcowym zapytaniu. Można je wykonać osobno. W tym celu używana jest instrukcja WITH .
Pozwala na utworzenie wirtualnej tabeli (nazwanego zapytania), a jej wygląd określa szablon:
WITH Name AS (request)
Często zdarza się, że zapytanie podrzędne zawiera kolumny bez nazw, takie jak COUNT(*), którym nie przypisano unikatowej nazwy. W takim przypadku instrukcja WITH umożliwia określenie nowych nazw kolumn dla podzapytania.
Jego drugą postać podaje szablon:
WITH Name(column1, column2, …) AS (request)
Możesz używać dowolnej liczby wirtualnych tabel (nazwanych zapytań) i odwoływać się w nich do siebie. Ogólna forma Twojej prośby będzie miała mniej więcej taką postać:
WITH name1 AS (request1),
name2 AS (request2),
name3 AS (request3)
SELECT * FROM name1 JOIN name2 ON …
Teraz weźmy nasze przerażające zapytanie:
SELECT * FROM employee e JOIN (
SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline
FROM task
) t ON e.id = t.emploee_id
I przepisz to, używając instrukcji WITH:
WITH task2(id, employee_id, name, deadline)
AS (SELECT id, IFNULL(employee_id, 4), name, deadline FROM task)
SELECT * FROM employee e JOIN task2 t ON e.id = t.emploee_id
Lub możesz obejść się bez nazw kolumn, ale wtedy będziesz musiał określić alias dla funkcji IFNULL():
WITH task2 AS (
SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline FROM task
)
SELECT * FROM employee e JOIN task2 t ON e.id = t.emploee_id
GO TO FULL VERSION