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谢谢
这是一个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.