SQL Server 中 CROSS APPLY 使用教程

CROSS APPLY 是 SQL Server 中一个强大的运算符,用于将表值函数的结果与源表的每行记录进行关联。它类似于 JOIN,但特别适用于需要为源表每行调用表值函数的场景。

一、CROSS APPLY 基本语法

SELECT 列名
FROM 源表
CROSS APPLY 表值函数(源表.列作为参数) AS 别名;

二、CROSS APPLYJOIN 的区别

  • JOIN 用于关联两个表,基于匹配条件
  • CROSS APPLY 用于为源表的每行记录调用表值函数,并将结果与该行关联
  • CROSS APPLY 可以使用源表的列作为函数参数,这是普通 JOIN 做不到的

三、使用场景示例

1. 准备测试环境

首先创建示例表和表值函数:

-- 创建产品表
CREATE TABLE Products (
    ProductID INT PRIMARY KEY,
    ProductName VARCHAR(50),
    Price DECIMAL(10,2)
);

-- 插入测试数据
INSERT INTO Products VALUES
(1, '笔记本电脑', 5999.99),
(2, '智能手机', 3999.99),
(3, '平板电脑', 2499.99);

-- 创建表值函数:返回价格在指定范围内的产品
CREATE FUNCTION GetRelatedProducts(@Price DECIMAL(10,2))
RETURNS TABLE
AS
RETURN (
    SELECT ProductID, ProductName, Price
    FROM Products
    WHERE Price BETWEEN @Price * 0.8 AND @Price * 1.2 -- 价格在80%-120%范围内
);
2. 使用 CROSS APPLY 关联数据

为每个产品找到价格相近的相关产品:

SELECT 
    p.ProductID AS 原产品ID,
    p.ProductName AS 原产品名称,
    p.Price AS 原产品价格,
    rp.ProductID AS 相关产品ID,
    rp.ProductName AS 相关产品名称,
    rp.Price AS 相关产品价格
FROM Products p
CROSS APPLY GetRelatedProducts(p.Price) rp
ORDER BY p.ProductID, rp.ProductID;

结果说明
查询会为 Products 表中的每个产品调用 GetRelatedProducts 函数,并返回价格相近的产品,形成多行结果。

3. CROSS APPLYOUTER APPLY 的对比
  • CROSS APPLY:只返回源表中能通过函数得到结果的记录(类似内连接)
  • OUTER APPLY:返回源表所有记录,即使函数无结果(类似左外连接)
-- 示例:使用 OUTER APPLY
SELECT 
    p.ProductID,
    p.ProductName,
    rp.ProductName AS 相关产品
FROM Products p
OUTER APPLY GetRelatedProducts(p.Price * 10) rp; -- 故意使用不匹配的参数

四、实际应用案例

1. 处理 JSON 数据

当表中包含 JSON 字段时,CROSS APPLY 可用于解析 JSON 数组:

-- 假设表中有JSON字段
CREATE TABLE Orders (
    OrderID INT,
    OrderDetails NVARCHAR(MAX) -- 存储JSON数组
);

-- 解析JSON并关联
SELECT 
    o.OrderID,
    j.[key] AS 明细序号,
    j.value AS 产品ID
FROM Orders o
CROSS APPLY OPENJSON(o.OrderDetails, '$.Products') j;
2. 分页查询

结合表值函数实现分页:

CREATE FUNCTION GetPagedData(@PageSize INT, @PageNum INT)
RETURNS TABLE
AS
RETURN (
    SELECT * 
    FROM Products
    ORDER BY ProductID
    OFFSET (@PageNum - 1) * @PageSize ROWS
    FETCH NEXT @PageSize ROWS ONLY
);

-- 使用APPLY查询多页数据
SELECT *
FROM (VALUES (1), (2)) AS Pages(PageNum)
CROSS APPLY GetPagedData(1, Pages.PageNum);

五、注意事项

  1. CROSS APPLY 适用于 SQL Server 2005 及以上版本
  2. 当表值函数返回大量数据时,需注意性能影响,建议添加适当索引
  3. 与表值函数配合使用时,确保函数逻辑高效
  4. 如需返回源表所有记录(包括无匹配结果的),使用 OUTER APPLY

通过 CROSS APPLY,可以灵活地将表值函数的结果与源表数据关联,特别适合处理需要基于每行记录动态生成结果的场景。

posted @ 2025-07-31 10:43  陆陆无为而治者  阅读(291)  评论(0)    收藏  举报