Zagnieżdżone zapytania w SQL
Język SQL umożliwia zagnieżdżanie jednego zapytania w innym zapytaniu. Dzięki temu możliwe jest napisanie jednego bardzo dużego zapytania, które zrobi coś dużego i złożonego, chociaż czytelność kodu jest znacznie ograniczona.
W zależności od tego, ile wartości zwracają podzapytania, zmienia się obszar, w którym można je zastosować. W sumie są trzy opcje:
- Podzapytanie zwraca jedną wartość (jedna kolumna i jeden wiersz).
- Podzapytanie zwraca listę wartości (tabelę z jedną kolumną).
- Podzapytanie zwraca tabelę (wiele kolumn, dowolna liczba wierszy).
Spójrzmy na jeden przykład dla każdego przypadku.
Podzapytanie z wynikiem skalarnym
Znajdźmy listę wszystkich naszych pracowników z tabeli pracowników, których wynagrodzenie jest wyższe niż średnia dla firmy. Jak możemy to zrobić?
Możemy łatwo filtrować pracowników, porównując ich wynagrodzenie ze średnią, jeśli znamy ją z góry. Jednocześnie napisaliśmy już zapytanie, które pozwala nam obliczyć średnie wynagrodzenie pracowników firmy. Zapamiętajmy to:
SELECT AVG(salary) FROM employee
Następnie MySQL zwrócił nam wartość: 76833.3333 .
Jak teraz znaleźć listę wszystkich pracowników, których zarobki są powyżej średniej? To również bardzo proste:
SELECT * FROM employee
WHERE salary > 76833.3333
Wynikiem tego zapytania będzie:
ID | nazwa | zawód | wynagrodzenie |
---|---|---|---|
1 | Iwanow Iwan | Programista | 100000 |
2 | Pietrow Pietr | Programista | 80000 |
4 | Rabinowicz Mojsza | Dyrektor | 200000 |
A teraz po prostu łączymy oba żądania, podstawiając pierwsze żądanie zamiast wartości 76833:
SELECT * FROM employee
WHERE salary > (SELECT AVG(salary) FROM employee)
Wynik tego zapytania będzie taki sam:
ID | nazwa | zawód | wynagrodzenie |
---|---|---|---|
1 | Iwanow Iwan | Programista | 100000 |
2 | Pietrow Pietr | Programista | 80000 |
4 | Rabinowicz Mojsza | Dyrektor | 200000 |
Podzapytanie z listą wartości
Czy pamiętasz, że kiedyś mieliśmy zadanie - znaleźć wszystkie rekordy z jednej tabeli, dla których nie ma odpowiednich rekordów z innej?
Było też takie zdjęcie:
![](https://cdn.codegym.cc/images/article/a0eff64c-0bb4-4480-833e-c1305cd03a5e/512.jpeg)
Jeśli się nie mylę, zadanie wygląda następująco: wyświetl listę wszystkich pracowników z tabeli pracowników, dla których nie ma zadań w tabeli zadań .
Znajdźmy również rozwiązanie w dwóch krokach.
Najpierw napiszmy zapytanie, które zwróci id wszystkich pracowników, którzy mają zadania w tabeli zadań. Pamiętaj tylko o dwóch rzeczach:
- usuń duplikaty - użyj słowa kluczowego DISTINCT.
- usuń wartości NULL z wyniku.
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
I oto otrzymaliśmy piękny wynik takiej prośby:
dowód pracownika |
---|
1 |
2 |
5 |
4 |
6 |
Zapiszmy to tymczasowo dla wygody jako ciąg: 1,2,5,4,6. Teraz napiszmy drugie zapytanie - do tabeli pracowników, które zwróci listę pracowników, których id nie znajduje się na pierwszej liście:
SELECT * FROM employee
WHERE id NOT IN (1,2,5,4,6)
I wynik tego zapytania:
ID | nazwa | zawód | wynagrodzenie | wiek | data_dołączenia |
---|---|---|---|---|---|
3 | Iwanow Siergiej | Próbnik | 40000 | trzydzieści | 2014-01-01 |
A teraz, podobnie jak w poprzednim przykładzie, możesz połączyć oba żądania, po prostu zastępując treść pierwszego żądania zamiast listy id.
SELECT * FROM employee
WHERE id NOT IN (
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
)
GO TO FULL VERSION