Xen*_*ger 0 sql t-sql sql-server row-number
目标是使用尽可能少的资源返回分区的第一行.到目前为止,我已经看到了使用建议:
with customerinfo_CTE as
(
select row_number() over(partition by customer order by year desc) as RNumber, *
from customerInfo
)
select *
from customerinfo_CTE
where RNumber = 1
Run Code Online (Sandbox Code Playgroud)
所以,我有一个customerInfo表,我们跟踪过去的客户详细信息(IE:联系信息,公司名称等).我此时正在使用CTE,但也可以使用#Temp Table或@Variable Table.
我希望有一种方法可以通过在连接或脚本的其他部分中使用它之前获得CTE(或其他)中唯一的年度第一条记录来提高性能.
现在,我正在使用:
with customerinfo_CTE as
(
select row_number() over(partition by customer order by year desc) as RNumber, *
from customerInfo
)
select *
from customerOrders a
inner join customerinfo_CTE b
on a.CustomerID = b.CustomerID
where b.RNumber = 1
Run Code Online (Sandbox Code Playgroud)
虽然这给了我想要的结果,但我希望有一种方法可以减少它以获得CTE声明中的第一个结果,而不必在连接的where子句中过滤后端.
提前致谢.
交叉应用使用内联视图来获取订单的关联信息记录,但使用交叉应用运算符(实际上不是连接),它为customerOrders中的EACH记录执行此操作,根据在客户端中定义的顺序返回每个客户的TOP 1记录.内联视图.
SELECT *
FROM CUSTOMERORDERS A
CROSS APPLY (SELECT top 1 *
FROM customerInfo B
WHERE A.CustomerID = B.customerID
ORDER by year desc) C
Run Code Online (Sandbox Code Playgroud)
虽然基于名字的表格似乎对我不利; 但根据你的例子似乎是正确的.
我可以看到很多订单,但有1条信息记录...所以我认为你想要按订单年份的最高订单......但也许不是.
那么也许你的意思是这个?
SELECT *
FROM CustomerInfo A
CROSS APPLY (SELECT top 1 *
FROM CUSTOMERORDERS B
WHERE A.CustomerID = B.customerID
ORDER by year desc) C
Run Code Online (Sandbox Code Playgroud)
但也许你每年都有每个客户的信息记录...所以也许不是..
还有一篇相关文章解释了应用用法以及一些很好的例子,以及为什么可以提升性能:https://www.mssqltips.com/sqlservertip/1958/sql-server-cross-apply-and-outer-apply/