sql server OUTER APPLY使用

一、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

优势:

  1. 逐行过滤,只查当前行需要的数据
  2. 不生成临时结果集,内存占用极低
  3. 配合索引 = 极速查询

三、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

尤其适合关联视图、函数、子查询

相关推荐
robottt66619 分钟前
2026国产协作机器人排名与选型指南:越疆、遨博、节卡、珞石解析
大数据·数据库·人工智能
郑州光合科技余经理28 分钟前
本地生活系统:多业务订单字段怎么分账本导出
java·开发语言·前端·数据库·uni-app·php·ai编程
weixin_460443563 小时前
考试监控大屏为什么不能直接查数据库?WebSocket、Redis与实时数据聚合架构设计
数据库·redis·在线考试系统·培训考试系统·煤矿培训考试系统·煤矿在线考试系统·宏远培训考试系统
风哥2号3 小时前
数据库教程FGMT02‑生产环境Linux+Oracle19c安装配置与项目实战
linux·数据库·ffmpeg
九皇叔叔8 小时前
【第二章】Redis基础入门:Redis是什么、为什么快以及核心特性详解
数据库·redis·缓存
莫陌尛.8 小时前
Docker MySQL 删表卡死、执行超时(MDL锁阻塞)问题复盘与根治方案
mysql·docker·容器
云和恩墨8 小时前
删库不跑路,回滚极速触达——zData S“旁路日志”持续保护原理深剖
数据库
MetaLite8 小时前
SpringBoot接口分层规范-外网网关内部服务与参数边界
java·数据库·spring boot
Wang's Blog10 小时前
Java框架快速入门: Spring Security+OAuth2之元注解简化权限表达式
java·数据库·spring
毕业设计70310 小时前
(免费领源码) 基于微信小程序的预制菜商城的设计与实现25172-java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
vue.js·python·mysql·微信小程序·pycharm·微信开发者工具·推荐算法