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

标题: CROSS APPLY [打印本页]

作者: 郑全    时间: 2025-10-10 15:31
标题: CROSS APPLY
本帖最后由 郑全 于 2025-10-10 15:38 编辑

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

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

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


语法格式


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,可以更灵活地处理 “行与依赖该行的子结果集” 的关联场景,尤其在表值函数和嵌套数据处理中非常实用。



作者: 郑全    时间: 2025-10-10 15:38
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.




欢迎光临 重庆思庄Oracle、KingBase、PostgreSQL、Redhat认证学习论坛 (http://bbs.cqsztech.com/) Powered by Discuz! X3.2