阅读 86

SqlServer技巧:使用APPLY替代游标解决逐行运算问题

--数据准备
--
表值函数 dbo.SplitString:按照分隔符将文本转换为表 declare @str1 varchar(max) set @str1 = 7,8,9 SELECT * FROM dbo.SplitString(@str1,,,1) --示例:某表有Col1,Col2两列,想将Col2中的文本拆分为多行,并在拆分后保留Col1和Col2的对应关系 CREATE TABLE #TMP( NAME VARCHAR(100) NULL, STRING VARCHAR(MAX) NULL ) TRUNCATE TABLE #TMP INSERT INTO #TMP(NAME, STRING) VALUES(TEST111,2,3,4), (TEST222,6,7), (TEST222,null)

使用情形:

1. 想将某表关联表值函数返回的表

例如:某表有Col1,Col2两列,想将Col2中的文本拆分为多行,并在拆分后保留Col1和Col2的对应关系

--方法1:使用游标,逐行拆分后拼接(略)
--方法2:使用APPLY进行逐行运算

--根据某列一行变多行,并保留其他列的对应关系
SELECT C.NAME, A.Value
FROM #TMP C
CROSS APPLY dbo.SplitString(C.STRING,,,1) A --去除NULL列

SELECT C.NAME, A.Value
FROM #TMP C
OUTER APPLY dbo.SplitString(C.STRING,,,1) A --保留NULL列


2. 两表关联每个客户的前三笔交易,并展示客户信息

--方法1:用JOIN + ROW_NUMBER() 
--方法2:用APPLY + TOP

--每个客户的前三笔交易
--方法1:用ROW_NUMBER()
SELECT C.custid, C.companyname, A.orderid, A.orderdate
FROM Sales.Customers C
LEFT JOIN(
SELECT ROW_NUMBER()OVER(PARTITION BY custid ORDER BY orderdate DESC, orderid DESC) AS RN
, custid, orderid, empid, orderdate, requireddate
FROM Sales.Orders
) A ON C.custid=A.custid
WHERE A.RN <=3
ORDER BY custid, RN

--方法2:用APPLY + TOP
SELECT C.custid, C.companyname, A.orderid, A.orderdate
FROM Sales.Customers C
CROSS APPLY(
SELECT TOP 3 orderid, empid, orderdate, requireddate
FROM Sales.Orders O
WHERE O.custid=C.custid
ORDER BY orderdate DESC, orderid DESC) A
ORDER BY C.custid

 

原文:https://www.cnblogs.com/hawking8su/p/14652565.html

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐