Podzapytania (SQL Server)

  • 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 przez ANY lub ALL.
  • 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 i IN działają na SELECT * 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 i HAVING.
  • nie można używać z podzapytaniami, które zawierają GROUP BY.
  • COMPUTE i INTO.
  • 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.

Write a Comment

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *