右外连接Vs.外层申请

时间:2019-10-10 18:36:44

标签: sql sql-server tsql join

RIGHT JOINOUTER APPLY有什么区别?

在我的通知中,我看到将表与RIGHT JOIN结合使用时,可以像使用INNER JOIN一样正常工作,但是当涉及OUTER APPLY时,我们到底在用什么进行测试? / p>

如果没有太大的区别,那么从查询成本方面进行解释?

1 个答案:

答案 0 :(得分:-1)

这在PostgreSQL中更容易理解,因为它们使用LATERAL而不是APPLY,其中包括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允许您从外部查询中引用子查询中的列。您不能通过联接执行此操作。下面是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

左加入和左加入使用外部应用

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