Это легче понять в PostgreSQL, потому что вместо APPLY они используют LATERAL
, который включает опции LEFT и RIGHT. SQL Server APPLY не имеет LEFT или RIGHT, поэтому вам нужно понимать разницу между LEFT и RIGHT таблицами.
SELECT <something(s)>
FROM <table1> -- This is the LEFT TABLE
JOIN <table2> -- This is the RIGHT TABLE
ON...
JOIN и APPLY - это операторы таблиц, то есть они работают с таблицами. Разница в том, что APPLY позволяет ссылаться на столбцы в подзапросе из внешнего запроса. Вы не можете сделать это с помощью соединения. Ниже приведены три примера применения. Сначала для ВНУТРЕННЕГО СОЕДИНЕНИЯ, затем как ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ и, наконец, как ПРАВИЛЬНОЕ НАРУЖНОЕ СОЕДИНЕНИЕ.
ВНУТРЕННЕЕ СОЕДИНЕНИЕ И ВНУТРЕННЕЕ СОЕДИНЕНИЕ С ИСПОЛЬЗОВАНИЕМ CROSS APPLY
DECLARE @t TABLE (SomeId INT); INSERT @t VALUES (1),(2),(3),(4);
BEGIN
SELECT t.SomeId, v.Id
FROM @t AS t
INNER JOIN (VALUES (1),(2),(5)) AS v(Id)
ON t.SomeId = v.Id;
SELECT t.SomeId, inlineFunction.Id
FROM @t AS t --<< @t is the "LEFT" Table
CROSS APPLY
(
SELECT v.ID
FROM (VALUES (1),(2),(5)) AS v(Id)
WHERE t.SomeId = v.Id
) AS inlineFunction; -- --<< This subquery is the "RIGHT" Table
END
Оба Возврат:
SomeId Id
----------- -----------
1 1
2 2
LEFT JOIN и LEFT JOIN с помощью внешнего приложения
DECLARE @t TABLE (SomeId INT); INSERT @t VALUES (1),(2),(3),(4);
BEGIN
SELECT t.SomeId, v.Id
FROM @t AS t
LEFT JOIN (VALUES (1),(2),(5)) AS v(Id)
ON t.SomeId = v.Id;
SELECT t.SomeId, inlineFunction.Id
FROM @t AS t
OUTER APPLY
(
SELECT v.ID
FROM (VALUES (1),(2),(5)) AS v(Id)
WHERE t.SomeId = v.Id --<< APPLY allows me to refernce columns from the Outer (parent query)
) AS inlineFunction;
END
Возвращает:
SomeId Id
----------- -----------
1 1
2 2
3 NULL
4 NULL
И, наконец, ...
ПРАВИЛЬНОЕ СОЕДИНЕНИЕ И ПРАВИЛЬНОЕ СОЕДИНЕНИЕ С ИСПОЛЬЗОВАНИЕМ НАРУЖНОГО ПРИМЕНЕНИЯ
DECLARE @t TABLE (SomeId INT); INSERT @t VALUES (1),(2),(3),(4);
BEGIN
SELECT t.SomeId, v.Id
FROM @t AS t
RIGHT JOIN (VALUES (1),(2),(5)) AS v(Id)
ON t.SomeId = v.Id;
SELECT inlineFunction.SomeId, v.Id
FROM (VALUES (1),(2),(5)) AS v(Id)
OUTER APPLY
(
SELECT t.SomeId
FROM @t AS t
WHERE t.SomeId = v.Id
) AS inlineFunction
END;
Оба возвращаются:
SomeId Id
----------- -----------
1 1
2 2
NULL 5