- 18.02.2018
- 21 minut na przeczytanie
-
- W
- M
- T
- M
- j
-
+3
Dotyczy: SQL Server (wszystkie obsługiwane wersje) Azure SQL Database Wystąpienie zarządzane Azure SQL Azure Synapse Analytics Równoległa hurtownia danych
Podzapytanie to zapytanie zagnieżdżone w SELECT
, INSERT
, UPDATE
lub DELETE
lub wewnątrz innego podzapytania. Podzapytanie może być używane wszędzie tam, gdzie dozwolone jest wyrażenie. W tym przykładzie podzapytanie jest używane jako wyrażenie kolumnowe o nazwie MaxUnitPrice w instrukcji SELECT.
Subquery Fundamentals
Podzapytanie jest również nazywana zapytaniem wewnętrznym lub wewnętrznym wyborem, podczas gdy instrukcja zawierająca podzapytanie jest również nazywana zapytaniem zewnętrznym lub wyborem zewnętrznym.
Wiele instrukcji języka Transact-SQL, które zawierają podzapytania, można alternatywnie sformułować jako sprzężenia. Inne pytania można zadawać tylko za pomocą podzapytań. W języku Transact-SQL zwykle nie ma różnicy w wydajności między instrukcją zawierającą podzapytanie a semantycznie równoważną wersją, która go nie zawiera. Jednak w niektórych przypadkach, gdy trzeba sprawdzić istnienie, łączenie zapewnia lepszą wydajność. W przeciwnym razie zagnieżdżone zapytanie musi zostać przetworzone dla każdego wyniku zapytania zewnętrznego, aby zapewnić eliminację duplikatów. W takich przypadkach podejście łączone przyniosłoby lepsze wyniki. Poniżej znajduje się przykład przedstawiający podzapytanie SELECT
i sprzężenie SELECT
, które zwracają ten sam zestaw wyników:
Podzapytanie zagnieżdżone w zewnętrznej instrukcji SELECT ma następujące składniki:
- Zwykłe zapytanie
SELECT
w tym zwykłe składniki listy wyboru. - Zwykła klauzula
FROM
zawierająca jedną lub więcej nazw tabel lub widoków. - Opcjonalny identyfikator
WHERE
klauzula. - Opcjonalna klauzula
GROUP BY
. - Opcjonalna
HAVING
klauzula.
Zapytanie SELECT podzapytania jest zawsze zawarte w nawiasach. Nie może zawierać klauzuli COMPUTE
ani FOR BROWSE
i może zawierać tylko klauzulę ORDER BY
, gdy jest również określona klauzula TOP.
Podzapytanie może być zagnieżdżone w klauzuli WHERE
lub HAVING
zewnętrznej SELECT
, INSERT
, UPDATE
lub DELETE
lub wewnątrz innego podzapytania. Możliwe jest do 32 poziomów zagnieżdżania, chociaż limit zależy od dostępnej pamięci i złożoności innych wyrażeń w zapytaniu. Poszczególne zapytania mogą nie obsługiwać zagnieżdżania do 32 poziomów. Podzapytanie może pojawić się wszędzie tam, gdzie można użyć wyrażenia, jeśli zwraca pojedynczą wartość.
Jeśli tabela występuje tylko w podzapytaniu, a nie w zapytaniu zewnętrznym, wówczas kolumn z tej tabeli nie można uwzględnić w wyjście (lista wyboru zewnętrznego zapytania).
Instrukcje zawierające podzapytanie zwykle przyjmują jeden z następujących formatów:
- WHERE wyrażenie IN (podzapytanie)
- WHERE wyrażenie operator porównania (podzapytanie)
- GDZIE ISTNIEJE (podzapytanie)
W niektórych instrukcjach języka Transact-SQL podzapytanie można oceniać tak, jakby było niezależnym pytanie. Koncepcyjnie wyniki podzapytania są podstawiane do zapytania zewnętrznego (chociaż nie jest to koniecznie sposób, w jaki SQL Server faktycznie przetwarza instrukcje Transact-SQL z podzapytaniami).
Istnieją trzy podstawowe typy podzapytań. Te, które:
- działają na listach wprowadzonych za pomocą
IN
lub takie, które zostały zmodyfikowane przez operator porównania przezANY
lubALL
. - Są wprowadzane za pomocą niezmodyfikowanego operatora porównania i muszą zwracać pojedynczą wartość.
- Czy testy istnienia są wprowadzane za pomocą
EXISTS
.
Reguły podzapytań
Podzapytanie podlega następującym ograniczeniom:
- Lista wyboru podzapytania wprowadzona za pomocą operatora porównania może zawierać tylko jedno wyrażenie lub nazwę kolumny (z wyjątkiem tego, że
EXISTS
iIN
działają naSELECT *
lub odpowiednio listę). - Jeśli klauzula
WHERE
zapytania zewnętrznego zawiera nazwę kolumny, musi być kompatybilna z połączeniami z kolumną na liście wyboru podzapytania. - Typy danych ntext, text i image nie mogą być używane na liście wyboru podzapytań.
- Ponieważ muszą zwracać pojedynczą wartość, podzapytania wprowadzane przez niezmodyfikowany operator porównania (jeden nie następuje po nim słowo kluczowe ANY ani ALL) nie może zawierać klauzul
GROUP BY
iHAVING
. - nie można używać z podzapytaniami, które zawierają GROUP BY.
-
COMPUTE
iINTO
. -
ORDER BY
można określić tylko wtedy, gdy określono równieżTOP
. - Widok utworzony za pomocą podzapytania nie może zostać zaktualizowany.
- Lista wyboru podzapytania wprowadzona za pomocą
EXISTS
ma zgodnie z konwencją gwiazdkę ( *) zamiast pojedynczej nazwy kolumny. Reguły podzapytania wprowadzone za pomocąEXISTS
są takie same, jak w przypadku standardowej listy wyboru, ponieważ podzapytanie wprowadzone za pomocąEXISTS
tworzy istnienie test i zwraca TRUE lub FALSE zamiast danych.
Kwalifikujące nazwy kolumn w podzapytaniach
W poniższym przykładzie kolumna BusinessEntityID w zapytania zewnętrznego jest niejawnie kwalifikowana przez nazwę tabeli w klauzuli FROM
(Sales.Store) w zapytaniu zewnętrznym. Odwołanie do CustomerID na liście wyboru podzapytania jest kwalifikowane przez klauzulę podzapytania FROM
, czyli przez tabelę Sales.Customer.
Ogólna zasada jest taka, że nazwy kolumn w instrukcji są niejawnie kwalifikowane przez tabelę, do której odwołuje się klauzula FROM
na tym samym poziomie. Jeśli kolumna nie istnieje w tabeli, do której odwołuje się klauzula FROM
podzapytania, jest ona niejawnie kwalifikowana przez tabelę, do której odwołuje się FROM
klauzula zapytania zewnętrznego.
Oto jak wygląda zapytanie z określonymi niejawnymi założeniami:
Nigdy nie jest źle do jawnego określenia nazwy tabeli i zawsze można zastąpić niejawne założenia dotyczące nazw tabel za pomocą jawnych kwalifikacji.
Ważne
Jeśli w podzapytaniu występuje odwołanie do kolumny, nie istnieje w tabeli, do której odwołuje się klauzula podzapytania „s FROM
, ale istnieje w tabeli, do której odwołuje się zapytanie zewnętrzne” s FROM
klauzula, zapytanie jest wykonywane bez błędów. SQL Server niejawnie kwalifikuje kolumnę w podzapytaniu za pomocą nazwy tabeli w zapytaniu zewnętrznym.
Wiele poziomów zagnieżdżenia
Podzapytanie może zawierać jedno lub więcej podzapytań. W instrukcji można zagnieżdżać dowolną liczbę podzapytań.
Poniższe zapytanie znajduje nazwiska pracowników, którzy są jednocześnie sprzedawcami.
Oto zestaw wyników.
Najbardziej wewnętrzne zapytanie zwraca identyfikatory sprzedawcy. Zapytanie na kolejnym wyższym poziomie jest oceniane przy użyciu tych identyfikatorów sprzedawcy i zwraca numery identyfikacyjne pracowników. Na koniec zapytanie zewnętrzne wykorzystuje identyfikatory kontaktów do znalezienia nazwisk pracowników.
Możesz również wyrazić to zapytanie jako złączenie:
Wiele zapytań można ocenić, wykonując jednokrotnie podzapytanie i zastępując wynikową wartość lub wartości w klauzuli WHERE
zapytania zewnętrznego. W zapytaniach, które zawierają skorelowane podzapytanie (znane również jako powtarzające się podzapytanie), podzapytanie zależy od zewnętrznego zapytania dla jego wartości. Oznacza to, że podzapytanie jest wykonywane wielokrotnie, raz dla każdego wiersza, który może zostać wybrany przez zapytanie zewnętrzne. To zapytanie pobiera po jednym wystąpieniu imienia i nazwiska każdego pracownika, dla którego premia w tabeli SalesPerson wynosi 5000 i dla którego numery identyfikacyjne pracowników są zgodne w tabelach Pracownik i Sprzedawca.
Oto zestaw wyników.
Poprzednie podzapytanie w tej instrukcji nie może zostać ocenione niezależnie od zapytania zewnętrznego. Potrzebuje wartości dla Employee.BusinessEntityID, ale ta wartość zmienia się, gdy SQL Server sprawdza różne wiersze w polu Employee.
Dokładnie tak to zapytanie jest oceniane: SQL Server rozważa każdy wiersz tabeli Employee w celu uwzględnienia w wynikach, zastępując wartość w każdym wierszu w zapytaniu wewnętrznym.Na przykład, jeśli SQL Server najpierw sprawdza wiersz pod kątem Syed Abbas
, zmienna Employee.BusinessEntityID przyjmuje wartość 285, którą SQL Server zastępuje do zapytania wewnętrznego.
Wynik to 0 (Syed Abbas
nie otrzymał premii, ponieważ jest nie sprzedawca), więc wynikiem zapytania zewnętrznego jest:
Ponieważ jest to fałsz, wiersz dla Syed Abbas
nie jest uwzględniany w wynikach.