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號