Używanie podzapytania skalarnych lub wielowartych

Ukończone

Podzapytywanie skalarne to wewnętrzna instrukcja SELECT w zapytaniu zewnętrznym zapisywana w celu zwrócenia pojedynczej wartości. Podzapytania skalarne mogą być używane w dowolnym miejscu w zewnętrznej instrukcji języka T-SQL, w której dozwolone jest jednowarte wyrażenie — na przykład w klauzuli SELECT, klauzuli WHERE, klauzuli HAVING, a nawet klauzuli FROM. Mogą być one również używane w instrukcjach modyfikacji danych, takich jak UPDATE lub DELETE.

Podzapytania wielowartych, jak sugeruje nazwa, mogą zwracać więcej niż jeden wiersz. Jednak nadal zwracają jedną kolumnę.

Podzapytania skalarne

Załóżmy, że chcesz pobrać szczegóły ostatniego złożonego zamówienia, przy założeniu, że jest to ta z najwyższą wartością SalesOrderID .

Aby znaleźć najwyższą wartość SalesOrderID , możesz użyć następującego zapytania:

SELECT MAX(SalesOrderID)
FROM Sales.SalesOrderHeader

To zapytanie zwraca pojedynczą wartość, która wskazuje najwyższą wartość dla identyfikatora OrderID w tabeli SalesOrderHeader .

Aby uzyskać szczegółowe informacje o tym zamówieniu, może być konieczne filtrowanie tabeli SalesOrderDetails na podstawie dowolnej wartości zwracanej przez powyższe zapytanie. To zadanie można wykonać, zagnieżdżając zapytanie, aby pobrać maksymalną wartość SalesOrderID w klauzuli WHERE zapytania, które pobiera szczegóły zamówienia.

SELECT SalesOrderID, ProductID, OrderQty
FROM Sales.SalesOrderDetail
WHERE SalesOrderID = 
   (SELECT MAX(SalesOrderID)
    FROM Sales.SalesOrderHeader);

Aby napisać podzapytywanie skalarne, należy wziąć pod uwagę następujące wskazówki:

  • Aby oznaczyć zapytanie jako podzapytywanie, należy je ująć w nawiasy.
  • Wiele poziomów podzapytania jest obsługiwanych w języku Transact-SQL. W tym module rozważymy tylko zapytania dwu-poziomowe (jedno zapytanie wewnętrzne w ramach jednego zapytania zewnętrznego), ale obsługiwane są maksymalnie 32 poziomy.
  • Jeśli podzapytywanie nie zwraca żadnych wierszy (pusty zestaw), wynik podzapytania jest wartością NULL. Jeśli w twoim scenariuszu nie ma zwracanych wierszy, upewnij się, że zapytanie zewnętrzne może bezpiecznie obsłużyć wartość NULL, oprócz innych oczekiwanych wyników.
  • Zapytanie wewnętrzne powinno zwykle zwracać jedną kolumnę. Wybranie wielu kolumn w podzapytaniu jest prawie zawsze błędem. Jedynym wyjątkiem jest wprowadzenie podzapytania za pomocą słowa kluczowego EXISTS.

Podzapytywanie skalarne może być używane w dowolnym miejscu w zapytaniu, w którym oczekiwano wartości, w tym na liście SELECT. Możemy na przykład rozszerzyć zapytanie, które pobrało szczegóły dla ostatniego zamówienia, aby uwzględnić średnią ilość uporządkowanych elementów, aby porównać ilość uporządkowaną w najnowszej kolejności ze średnią dla wszystkich zamówień.

SELECT SalesOrderID, ProductID, OrderQty,
    (SELECT AVG(OrderQty)
     FROM SalesLT.SalesOrderDetail) AS AvgQty
FROM SalesLT.SalesOrderDetail
WHERE SalesOrderID = 
    (SELECT MAX(SalesOrderID)
     FROM SalesLT.SalesOrderHeader);

Wielowarte podzapytania

Wielowartość podzapytania jest odpowiednia do zwracania wyników przy użyciu operatora IN. Poniższy hipotetyczny przykład zwraca wartości CustomerID, SalesOrderID dla wszystkich zamówień złożonych przez klientów w Kanadzie.

SELECT CustomerID, SalesOrderID
FROM Sales.SalesOrderHeader
WHERE CustomerID IN (
    SELECT CustomerID
    FROM Sales.Customer
    WHERE CountryRegion = 'Canada');

W tym przykładzie, jeśli wykonano tylko zapytanie wewnętrzne, zostanie zwrócona kolumna wartości CustomerID z wierszem dla każdego klienta w Kanadzie.

W wielu przypadkach podzapytania wielowartościowe można łatwo zapisywać przy użyciu sprzężeń. Na przykład poniżej przedstawiono zapytanie, które używa sprzężenia w celu zwrócenia tych samych wyników co w poprzednim przykładzie:

SELECT c.CustomerID, o.SalesOrderID
FROM Sales.Customer AS c
JOIN Sales.SalesOrderHeader AS o
    ON c.CustomerID = o.CustomerID
WHERE c.CountryRegion = 'Canada';

Jak więc zdecydować, czy napisać zapytanie obejmujące wiele tabel jako JOIN, czy z podzapytaniem? Czasami zależy to tylko od tego, z czym jesteś bardziej wygodny. Większość zagnieżdżonych zapytań, które są łatwo konwertowane na elementy JOIN, faktycznie zostanie przekonwertowana na sprzężenie wewnętrzne. W przypadku takich zapytań nie ma wówczas żadnej rzeczywistej różnicy w pisaniu zapytania w jeden sposób a inny.

Należy pamiętać o jednym ograniczeniu, że w przypadku korzystania z zapytania zagnieżdżonego wyniki zwrócone do klienta mogą zawierać tylko kolumny z zapytania zewnętrznego. Jeśli więc musisz zwrócić kolumny z obu tabel, należy napisać zapytanie przy użyciu funkcji JOIN.

Na koniec istnieją sytuacje, w których zapytanie wewnętrzne musi wykonywać znacznie bardziej skomplikowane operacje niż proste pobieranie w naszych przykładach. Ponowne zapisywanie złożonych podzapytania przy użyciu funkcji JOIN może być trudne. Wielu deweloperów sql znaleźć podzapytania działa najlepiej w przypadku skomplikowanego przetwarzania, ponieważ umożliwia podzielenie przetwarzania na mniejsze kroki.