SQL Server 中 CROSS APPLY 使用教程
CROSS APPLY 是 SQL Server 中一个强大的运算符,用于将表值函数的结果与源表的每行记录进行关联。它类似于 JOIN,但特别适用于需要为源表每行调用表值函数的场景。
一、CROSS APPLY 基本语法
SELECT 列名
FROM 源表
CROSS APPLY 表值函数(源表.列作为参数) AS 别名;
二、CROSS APPLY 与 JOIN 的区别
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 APPLY 与 OUTER 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);
五、注意事项
CROSS APPLY适用于 SQL Server 2005 及以上版本- 当表值函数返回大量数据时,需注意性能影响,建议添加适当索引
- 与表值函数配合使用时,确保函数逻辑高效
- 如需返回源表所有记录(包括无匹配结果的),使用
OUTER APPLY
通过 CROSS APPLY,可以灵活地将表值函数的结果与源表数据关联,特别适合处理需要基于每行记录动态生成结果的场景。
有志者,事竟成,破釜沉舟,百二秦关终属楚; 苦心人,天不负,卧薪尝胆,三千越甲可吞吴。

浙公网安备 33010602011771号