一、OUTER APPLY = 对每行数据,执行一次子查询,并把结果拼接到当前行
- 相当于 "带行参数的 LEFT JOIN"
- 专门解决:子查询需要引用外部表字段 的场景
- 性能远优于传统的
LEFT JOIN + 子查询
和 CROSS APPLY / LEFT JOIN 的区别

二、最简单的示例
场景
有 学生表 + 成绩表,要给每个学生查最新 1 条成绩
传统 LEFT JOIN(写起来麻烦、性能差)
sql
SELECT s.*, sc.Score
FROM Student s
LEFT JOIN (
SELECT TOP 1 Score FROM Score WHERE StudentId = s.StudentId -- 报错!无法引用 s
) sc ON 1=1
OUTER APPLY(完美解决)
sql
SELECT s.*, sc.Score
FROM Student s
OUTER APPLY (
-- 这里可以直接用 s.StudentId,每行执行一次
SELECT TOP 1 Score
FROM Score
WHERE StudentId = s.StudentId
ORDER BY CreateTime DESC
) sc
结果
- 所有学生都会显示
- 有成绩 → 显示成绩
- 无成绩 → 显示 NULL
优势:
- 逐行过滤,只查当前行需要的数据
- 不生成临时结果集,内存占用极低
- 配合索引 = 极速查询
三、OUTER APPLY 最常用 3 大场景
1. 取每组 TOP N 数据(最常用)
每个分类取最新 / 最贵一条
sql
SELECT *
FROM 分类表 c
OUTER APPLY (
SELECT TOP 1 * FROM 商品表 g
WHERE g.分类ID = c.ID
ORDER BY g.创建时间 DESC
) g
2. 子查询必须引用外部表字段
传统 JOIN 做不到,只有 APPLY 可以
3. 替代复杂的 LEFT JOIN,简化 SQL
尤其适合关联视图、函数、子查询