| 運算子 | 行為 |
|---|---|
| CROSS APPLY | 右側表值函數回傳空集合 → 左側列被過濾掉 (相當於 INNER JOIN) |
| OUTER APPLY | 右側回傳空集合 → 左側列保留,右側欄位補 NULL (相當於 LEFT JOIN) |
-- 表值函數:字串分割
CREATE FUNCTION dbo.Split(@Sql VARCHAR(8000), @Sep VARCHAR(10))
RETURNS @t TABLE (Val VARCHAR(100))
AS BEGIN
DECLARE @i INT = CHARINDEX(@Sep, @Sql);
WHILE @i > 0 BEGIN
INSERT @t VALUES (LEFT(@Sql, @i-1));
SET @Sql = SUBSTRING(@Sql, @i+1, LEN(@Sql)-@i);
SET @i = CHARINDEX(@Sep, @Sql);
END
IF @Sql <> '' INSERT @t VALUES (@Sql);
RETURN;
END
GO
-- 使用:將 LargeTable.Name 以 ':' 拆成多列
SELECT lt.Id, s.Val
FROM dbo.LargeTable lt
CROSS APPLY dbo.Split(lt.Name, ':') s
WHERE s.Val <> '';
-- 表值函數:依供應商取 Top 2
CREATE FUNCTION dbo.fn_TopProducts(@SupId INT)
RETURNS TABLE
AS RETURN
SELECT TOP 2 Id AS ProductId, ProductName, UnitPrice
FROM dbo.Products
WHERE SupplierId = @SupId
ORDER BY UnitPrice DESC;
GO
-- OUTER APPLY:無產品供應商仍保留
SELECT s.Id AS SupplierId, s.CompanyName, p.ProductId, p.UnitPrice
FROM dbo.Supplier s
OUTER APPLY dbo.fn_TopProducts(s.Id) p;
CROSS APPLY fn_getsubtree(D.deptmgrid) 只回傳有主管的部門;
OUTER APPLY 會多出一列 Gardening / NULL / NULL ... (無主管部門)。
SQL Server 2005+ 全版本支援;Azure SQL Database / Managed Instance 亦支援。