重庆思庄Oracle、KingBase、PostgreSQL、Redhat认证学习论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 444|回复: 1
打印 上一主题 下一主题

CROSS APPLY

[复制链接]
跳转到指定楼层
楼主
发表于 2025-10-10 15:31:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 郑全 于 2025-10-10 15:38 编辑

今天看到一个  CROSS APPLY SQL语句,记录一下:

CROSS APPLY 是 SQL 中的一种表操作符,主要用于将表表达式(如子查询、表值函数)与左侧的表进行关联,类似于 JOIN,但更灵活,尤其适用于将左侧表的列作为参数传递给右侧的表值函数或子查询的场景。

核心作用
    CROSS APPLY 会将左侧表的每一行与右侧表表达式(如函数)的结果进行 “交叉应用”,最终返回所有匹配的组合。

  • 若右侧表表达式返回空结果,对应的左侧行不会出现在结果中(类似 INNER JOIN 的行为)。
  • 若需要保留左侧行(即使右侧无结果),可使用 OUTER APPLY(类似 LEFT JOIN)。

语法格式


SELECT 列名 FROM 左侧表 CROSS APPLY (  表值函数(左侧表.列名)   -- 或子查询,可引用左侧表的列) AS 别名;

典型使用场景1. 与表值函数结合(最常用)
   假设有一个表值函数 fn_GetOrdersByCustomerId(@CustomerId),用于返回指定客户的所有订单。
  使用 CROSS APPLY 可一次性获取所有客户及其对应的订单:

   -- 客户表
  SELECT *
    FROM Customers c
    CROSS APPLY fn_GetOrdersByCustomerId(c.CustomerId) o;

等价于对每个客户执行一次函数,并将结果与客户信息关联。

2. 与子查询结合(引用左侧表列)
  当子查询需要依赖左侧表的列作为条件时,CROSS APPLY 比普通 JOIN 更方便(JOIN 的子查询无法直接引用左侧表的列)。

例如,查询每个员工的最近 3 条销售记录:

  SELECT e.EmployeeId, e.Name, s.SaleDate, s.Amount
    FROM Employees e
   CROSS APPLY (   -- 子查询引用左侧表的 EmployeeId  
     SELECT TOP 3 SaleDate, Amount   
       FROM Sales   
     WHERE EmployeeId = e.EmployeeId   -- 依赖左侧表的列  
     ORDER BY SaleDate DESC) s;

3. 处理 JSON/XML 数据(提取嵌套内容)
   在 SQL Server 中,可结合 OPENJSON 等函数解析 JSON 数据,用 CROSS APPLY 提取嵌套数组:

  -- 假设有一张表存储 JSON 格式的订单明细
  SELECT o.OrderId, j.ItemName, j.Quantity
     FROM Orders o
   CROSS APPLY OPENJSON(o.DetailsJson, '$.Items')  -- 解析 JSON 数组
     WITH (  ItemName VARCHAR(50) '$.Name',  Quantity INT '$.Qty') j;

与 JOIN 的区别
特性         
CROSS APPLY                    
INNER JOIN                             
右侧引用左侧列
允许(核心优势  )  
不允许(子查询无法直接引用左侧表)            
适用场景
表值函数、依赖左侧列的子查询
基于等值 / 非等值条件的常规关联
空结果处理
右侧为空时,左侧行不保留
无匹配时,行不保留(与 CROSS APPLY 一致)


注意事项
  • CROSS APPLY 是 SQL Server、Azure SQL 等数据库支持的语法,MySQL 不支持(MySQL 可用 LATERAL JOIN 替代,功能类似)。
  • 若需保留左侧所有行(即使右侧无结果),使用 OUTER APPLY(右侧为空时返回 NULL)。
  • 合理使用可简化复杂查询,但过度使用可能影响性能,需注意索引优化。

通过 CROSS APPLY,可以更灵活地处理 “行与依赖该行的子结果集” 的关联场景,尤其在表值函数和嵌套数据处理中非常实用。


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 支持支持 反对反对
回复

使用道具 举报

沙发
 楼主| 发表于 2025-10-10 15:38:33 | 只看该作者
SQL> select d.department_name,e.last_name,e.salary
  2    from employees e cross apply (select department_name from departments where department_id=e.department_id) d;

DEPARTMENT_NAME                LAST_NAME                     SALARY
------------------------------ ------------------------- ----------
Administration                 Whalen                          4400
Marketing                      Hartstein                      13000
Marketing                      Fay                             6000
Shipping                       Mourgos                         5800
Shipping                       Rajs                            3500
Shipping                       Davies                          3100
Shipping                       Matos                           2600
Shipping                       Vargas                          2500
IT                             Hunold                          9000
IT                             Ernst                           6000
IT                             Lorentz                         4200

DEPARTMENT_NAME                LAST_NAME                     SALARY
------------------------------ ------------------------- ----------
Sales                          Zlotkey                        10500
Sales                          Abel                           11000
Sales                          Taylor                          8600
Executive                      King                           24000
Executive                      Kochhar                        17000
Executive                      De Haan                        17000
Accounting                     Higgins                        12008
Accounting                     Gietz                           8300

19 rows selected.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|重庆思庄Oracle、Redhat认证学习论坛 ( 渝ICP备12004239号-4 )

GMT+8, 2026-4-18 07:22 , Processed in 0.215103 second(s), 19 queries .

重庆思庄学习中心论坛-重庆思庄科技有限公司论坛

© 2001-2020

快速回复 返回顶部 返回列表