SQL Server的指南APPLY AND JOIN关键字

Tho*_*mas 4 sql t-sql sql-server cross-apply

我正在阅读一篇关于使用apply & join关键字的文章.查看一些SQL,其中一个示例使用内部联接和其他使用apply关键字.

这是表pic

在此输入图像描述

SELECT E.EMPID, E.NAME, E.DEPTID, D.NAME 
FROM EMPLOYEE E 
INNER JOIN  DEPARTMENT D ON E.DEPTID = D.DEPTID

SELECT E.EMPID, E.NAME, E.DEPTID, CA.NAME 
FROM EMPLOYEE E
CROSS APPLY
    (SELECT * FROM DEPARTMENT D WHERE D.DEPTID = E.DEPTID) CA  
Run Code Online (Sandbox Code Playgroud)

两个查询都返回相同的输出和相同的执行计划.这是照片

在此输入图像描述 在此输入图像描述

再次使用外部应用和左外部连接

SELECT E.EMPID, E.NAME, E.DEPTID, D.NAME 
FROM EMPLOYEE E 
LEFT JOIN  DEPARTMENT D ON E.DEPTID = D.DEPTID

SELECT E.EMPID, E.NAME, E.DEPTID, OA.NAME 
FROM EMPLOYEE E
OUTER APPLY
    (SELECT * FROM DEPARTMENT D WHERE D.DEPTID = E.DEPTID) OA
Run Code Online (Sandbox Code Playgroud)

现在,两个查询再次生成相同的输出和相同的执行计划 所以我只是不明白应该使用什么样的情况OUTER APPLY或者CROSS APPLY代替内连接或左外连接?

所以如果可能跟其中一个应该使用相同的情况下OUTER APPLY or CROSS APPLY谢谢

Rem*_*anu 5

这是一个APPLY示例,无法重写为JOIN:

SELECT ...
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
Run Code Online (Sandbox Code Playgroud)

您可以将APPLY视为相关关系的JOIN.JOIN不允许相关,两个连接关系必须是独立的.例如,以下内容不正确:

select * 
from sys.objects o1
join (
    select * 
    from sys.objects o2
    where o1.object_id = o2.object_id) as o3
on 1=1;

Msg 4104, Level 16, State 1, Line 6
The multi-part identifier "o1.object_id" could not be bound.
Run Code Online (Sandbox Code Playgroud)

但是,同样可以表示为APPLY:

select * 
from sys.objects o1
cross apply (
    select * 
    from sys.objects o2
    where o1.object_id = o2.object_id) as o3;
Run Code Online (Sandbox Code Playgroud)

o1.object_id 在子查询可用,因为APPLY允许相关.最重要的用例是表值函数,如我原始示例中所示,因为APPLY允许将'main'表的列作为参数传递给函数.

CROSS APPLY和OUTER APPLY之间的区别与JOIN完全相同,OUTER情况允许返回匹配的行(APPLY返回空结果集),并在相应的内部表列中使用NULL.