Podzapytanie to instrukcja SELECT zagnieżdżona wewnątrz instrukcji SELECT, SELECT... DO, WSTAW... Instrukcja INTO, DELETE lub UPDATE albo w innej podzapytaniu.
Składnia
Do utworzenia podzapytania można użyć trzech form składni:
porównanie [ANY | WSZYSTKIE | SOME] (sqlstatement)
wyrażenie [NOT] IN (sqlstatement)
[NIE] EXISTS (sqlstatement)
Podzapytanie zawiera następujące segmenty:
Segment |
Opis |
Porównanie |
wyrażenie i operator porównania, który porównuje wyrażenie z wynikami podzapytania. |
wyrażenie |
Wyrażenie, dla którego przeszukiwany jest zestaw wyników podzapytania. |
instrukcja_sql |
Instrukcja SELECT zgodna z tym samym formatem i regułami co każda inna instrukcja SELECT. Musi być ujęta w nawiasy. |
Spostrzeżenia
Zamiast wyrażenia można użyć podzapytania na liście pól instrukcji SELECT lub klauzuli WHERE lub HAVING. W podzapytaniu należy użyć instrukcji SELECT w celu udostępnienia zestawu co najmniej jednej konkretnej wartości do oszacowania w wyrażeniu klauzuli WHERE lub HAVING.
Aby pobrać w zapytaniu głównym rekordy spełniające kryteria porównania z wszelkimi rekordami pobranymi w podzapytaniu, należy użyć predykatu ANY lub SOME, które są synonimem. W poniższym przykładzie są zwracane wszystkie produkty, których cena jednostkowa jest większa niż cena każdego produktu sprzedawanego z rabatem 25 procent lub większym:
SELECT * FROM Products WHERE UnitPrice > ANY (SELECT UnitPrice FROM OrderDetails WHERE Discount >= .25);
Orzeczenie ALL umożliwia pobranie tylko tych rekordów w zapytaniu głównym, które spełniają kryteria porównania ze wszystkimi rekordami pobranymi w podzapytaniu. Jeśli w poprzednim przykładzie zmieniono wartość ANY na ALL, zapytanie zwróci tylko te produkty, których cena jednostkowa jest większa niż w przypadku wszystkich produktów sprzedanych z rabatem 25 procent lub większym. Jest to o wiele bardziej restrykcyjne.
Predykat IN służy do pobierania tylko tych rekordów w zapytaniu głównym, dla których niektóre rekordy w podzapytaniu zawierają jednakową wartość. W poniższym przykładzie zwracane są wszystkie produkty z rabatem w wysokości co najmniej 25 procent:
SELECT * FROM Products WHERE ProductID IN (SELECT ProductID FROM OrderDetails WHERE Discount >= .25);
Z drugiej strony można użyć funkcji NIE IN, aby pobrać tylko te rekordy w zapytaniu głównym, dla których żaden rekord w podzapytaniu nie zawiera równej wartości.
W porównaniu prawda/fałsz należy użyć predykatu EXISTS (z opcjonalnym wyrazem zastrzeżonym NOT) w celu określenia, czy podzapytanie zwraca jakiekolwiek rekordy.
Aliasów nazw tabel można także używać w podzapytaniu, aby odwoływać się do tabel wymienionych w klauzuli FROM poza podzapytaniem. W poniższym przykładzie są zwracane imiona i nazwiska pracowników, których zarobki są równe lub większe niż średnia pensja wszystkich pracowników mających to samo stanowisko. Tabela Pracownicy ma alias "T1":
SELECT LastName, FirstName, Title, Salary FROM Employees AS T1 WHERE Salary >= (SELECT Avg(Salary) FROM Employees WHERE T1.Title = Employees.Title) Order by Title;
W poprzednim przykładzie słowo zastrzeżone AS jest opcjonalne.
Niektóre podkwitryny są dozwolone w zapytaniach krzyżowych — w szczególności jako orzeczenie (w klauzuli WHERE). Podkwitary jako dane wyjściowe (znajdujące się na liście SELECT) nie są dozwolone w zapytaniach krzyżowych.