SQL
крест применяется, наружный применяется
Поиск…
Основы CROSS APPLY и OUTER APPLY
Применить будет использоваться, когда функция table value в правильном выражении.
создайте таблицу отдела для хранения информации о департаментах. Затем создайте таблицу Employee, в которой хранятся сведения о сотрудниках. Обратите внимание: каждый сотрудник принадлежит отделу, поэтому таблица Employee имеет ссылочную целостность с таблицей Департамента.
Первый запрос выбирает данные из таблицы Department и использует CROSS APPLY для оценки таблицы Employee для каждой записи таблицы Department. Второй запрос просто присоединяется к таблице Департамента с таблицей Employee, и все соответствующие записи создаются.
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
Если вы посмотрите на результаты, которые они произвели, это точно такой же результат; Чем он отличается от JOIN и как он помогает в написании более эффективных запросов.
Первый запрос в сценарии # 2 выбирает данные из таблицы Department и использует OUTER APPLY для оценки таблицы Employee для каждой записи таблицы Department. Для тех строк, для которых нет совпадений в таблице Employee, эти строки содержат значения NULL, как вы можете видеть в случае строк 5 и 6. Второй запрос просто использует LEFT OUTER JOIN между таблицей Департамента и таблицей Employee. Как и ожидалось, запрос возвращает все строки из таблицы Department; даже для тех строк, для которых нет совпадений в таблице Employee.
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
Несмотря на то, что вышеупомянутые два запроса возвращают одну и ту же информацию, план выполнения будет бит другим. Но стоить разумно, не будет большой разницы.
Теперь настало время посмотреть, где действительно нужен оператор APPLY. В сценарии №3 я создаю табличную функцию, которая принимает параметр DepartmentID как параметр и возвращает всех сотрудников, принадлежащих этому отделу. Следующий запрос выбирает данные из таблицы Department и использует CROSS APPLY для объединения с созданной нами функцией. Он передает идентификатор отдела для каждой строки из выражения внешней таблицы (в нашем случае таблица Департамента) и оценивает функцию для каждой строки, подобной коррелированному подзапросу. Следующий запрос использует OUTER APPLY вместо CROSS APPLY и, следовательно, в отличие от CROSS APPLY, который возвращает только коррелированные данные, OUTER APPLY также возвращает некоррелированные данные, помещая NULL в отсутствующие столбцы.
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
Итак, теперь, если вам интересно, можем ли мы использовать простое соединение вместо вышеуказанных запросов? Тогда ответ НЕТ, если вы замените CROSS / OUTER APPLY в вышеуказанных запросах INNER JOIN / LEFT OUTER JOIN, укажите предложение ON (что-то как 1 = 1) и запустите запрос, вы получите «Идентификатор с несколькими частями», D.DepartmentID "не может быть связан". ошибка. Это связано с тем, что с JOINs контекст выполнения внешнего запроса отличается от контекста выполнения функции (или производной таблицы), и вы не можете привязать значение / переменную от внешнего запроса к функции в качестве параметра. Следовательно, для таких запросов требуется оператор APPLY.