Szukaj…


Podstawy aplikacji CROSS APPLY i OUTER APPLY

Zastosuj zostanie zastosowane, gdy funkcja wyceniona w tabeli we właściwym wyrażeniu.

utwórz tabelę działów, aby przechowywać informacje o działach. Następnie utwórz tabelę pracowników, która zawiera informacje o pracownikach. Należy pamiętać, że każdy pracownik należy do działu, dlatego tabela pracowników ma referencyjną integralność z tabelą działu.

Pierwsze zapytanie wybiera dane z tabeli działu i używa KRZYŻ APLIKACJI do oceny tabeli pracowników dla każdego rekordu tabeli działu. Drugie zapytanie po prostu łączy tabelę działu z tabelą pracownika i generowane są wszystkie pasujące rekordy.

SELECT *
FROM Department D
CROSS APPLY (
    SELECT *
    FROM Employee E
    WHERE E.DepartmentID = D.DepartmentID
) A
GO
SELECT *
FROM Department D
INNER JOIN Employee E
  ON D.DepartmentID = E.DepartmentID

Jeśli spojrzysz na uzyskane przez nich wyniki, jest to dokładnie ten sam zestaw wyników; Czym różni się od JOIN i jak pomaga pisać bardziej wydajne zapytania.

Pierwsze zapytanie w skrypcie nr 2 wybiera dane z tabeli działu i wykorzystuje ZEWNĘTRZNE ZASTOSOWANIE do oceny tabeli pracowników dla każdego rekordu tabeli działu. W przypadku wierszy, dla których nie ma dopasowania w tabeli pracowników, wiersze te zawierają wartości NULL, co widać w przypadku wierszy 5 i 6. Drugie zapytanie po prostu używa LEWEGO POŁĄCZENIA ZEWNĘTRZNEGO między tabelą działu a tabelą pracownika. Zgodnie z oczekiwaniami zapytanie zwraca wszystkie wiersze z tabeli działu; nawet dla tych wierszy, dla których nie ma dopasowania w tabeli pracowników.

SELECT *
FROM Department D
OUTER APPLY (
    SELECT *
    FROM Employee E
    WHERE E.DepartmentID = D.DepartmentID
) A
GO
SELECT *
FROM Department D
LEFT OUTER JOIN Employee E
  ON D.DepartmentID = E.DepartmentID
GO

Mimo że powyższe dwa zapytania zwracają te same informacje, plan wykonania będzie nieco inny. Ale pod względem kosztów nie będzie dużej różnicy.

Teraz nadszedł czas, aby zobaczyć, gdzie operator APPLY jest naprawdę wymagany. W skrypcie nr 3 tworzę funkcję o wartościach przechowywanych w tabeli, która przyjmuje parametr DepartmentID jako parametr i zwraca wszystkich pracowników należących do tego działu. Następne zapytanie wybiera dane z tabeli Departamentu i używa KRZYŻ ZASTOSUJ, aby połączyć się z utworzoną przez nas funkcją. Przekazuje DepartmentID dla każdego wiersza z wyrażenia tabeli zewnętrznej (w naszym przypadku tabela Department) i ocenia funkcję dla każdego wiersza podobnie do skorelowanego podzapytania. Następne zapytanie używa ZEWNĘTRZNEGO ZASTOSOWANIA zamiast ZASTOSOWANIA KRZYŻOWEGO, a zatem w przeciwieństwie do KRZYŻOWEGO ZASTOSOWANIA, które zwróciło tylko skorelowane dane, ZEWNĘTRZNE ZASTOSOWANIE zwraca również dane nieskorelowane, umieszczając wartości NULL w brakujących kolumnach.

CREATE FUNCTION dbo.fn_GetAllEmployeeOfADepartment (@DeptID AS int)
RETURNS TABLE
AS
  RETURN
  (
  SELECT
    *
  FROM Employee E
  WHERE E.DepartmentID = @DeptID
  )
GO
SELECT
  *
FROM Department D
CROSS APPLY dbo.fn_GetAllEmployeeOfADepartment(D.DepartmentID)
GO
SELECT
  *
FROM Department D
OUTER APPLY dbo.fn_GetAllEmployeeOfADepartment(D.DepartmentID)
GO

Więc teraz, jeśli zastanawiasz się, czy możemy użyć prostego łączenia zamiast powyższych zapytań? Zatem odpowiedź brzmi NIE, jeśli w powyższych zapytaniach zamienisz CROSS / OUTER APPLY na INNER JOIN / LEFT OUTER JOIN, podasz klauzulę ON (około 1 = 1) i uruchomisz zapytanie, otrzymasz „The multi-part identifier” D.DepartmentID „nie można związać”. błąd. Jest tak, ponieważ w przypadku JOIN kontekst wykonania zewnętrznego zapytania różni się od kontekstu wykonania funkcji (lub tabeli pochodnej) i nie można powiązać wartości / zmiennej z zewnętrznego zapytania z funkcją jako parametru. Dlatego operator APPLY jest wymagany do takich zapytań.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow