我在表变量中有一堆记录,如下所示:
Id ProductId Rank RankCreated
1 123213 2 2011-05-02
2 123213 4 2011-05-03
3 123213 1 2011-05-03
4 155432 10 2011-05-01
5 155432 10 2011-05-02
Id 是我添加到我的表变量中的标识列(稍后会解释为什么我需要它)。 ProductId 是一个产品。 Rank 是表示产品在给定时间的排名的值。 RankCreated 是Product 排名的时间。
我想做什么:
Calculate the "movement" between each product rank, for each product. Where "movement" is defined as current - previous.
所以“计算列”看起来像这样:
Id ProductId Rank RankCreated Movement
1 123213 2 2011-05-02 NULL
2 123213 4 2011-05-03 2
3 123213 1 2011-05-03 -3
4 155432 10 2011-05-01 NULL
5 155432 10 2011-05-02 0
我添加了 Id 列,这样我就可以用它来获取以前的记录。
以下是我如何将数据放入临时表:
insert into @rankhistories (productid, [rank], [rankcreated])
select a.ProductId, b.[rank]
from dbo.ProductRankHistories b
inner join dbo.Products a on a.ProductId = b.ProductId
order by a.ProductId, b.RankCreated
我真的看不出如何避免此处出现光标。该表变量中有 6000 多条记录,使用我的游标解决方案需要 5 秒,这是 Not Acceptable 。
有人能帮忙吗?
最佳答案
DECLARE @TV TABLE
(
Id INT IDENTITY(1,1) PRIMARY KEY,
ProductId INT,
Rank INT,
RankCreated DATE
)
/*Populate *6000 rows of random data*/
INSERT INTO @TV
SELECT TOP 6000
ROW_NUMBER() OVER (ORDER BY (SELECT 0)) / 9 AS ProductId,
CRYPT_GEN_RANDOM(1) % 10 AS Rank,
GETDATE() AS RankCreated
FROM master..spt_values v1,master..spt_values v2
SELECT t1.Id,
t1.ProductId,
t1.Rank,
t1.RankCreated,
t2.Rank - t1.Rank AS Movement
FROM @TV t1
LEFT MERGE JOIN @TV t2 ON t1.Id = t2.Id+1 AND t1.ProductId=t2.ProductId
ORDER BY t1.Id
关于sql-server - 帮助避免使用 CURSOR 进行列计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5971796/