sql-server - 帮助避免使用 CURSOR 进行列计算

标签 sql-server tsql sql-server-2008 cursor aggregate-functions

我在表变量中有一堆记录,如下所示:

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 是表示产品在给定时间的排名的值。 RankCreatedProduct 排名的时间。

我想做什么:

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/

相关文章:

sql-server - 使用 LINQ 时数据库性能开销有多大?

sql - 将 10k 行从表复制到其他服务器上的表

sql-server-2008 - T-SQL(MS SQL 2008),不带 'EXEC'或 'EXECUTE'词的执行过程

mysql - SQL 服务器 : How to override Error 0xc02020a1: Data Flow Task 1: Data conversion failed

sql - 在 SQL 中将时间转换为 12 小时格式

sql - 每次都覆盖值与查询以查看值是否已更改

sql-server - 从 SQL 语句创建 .txt 文件

sql - 如果日期重叠,则对行进行分组,并对它们进行排名

sql - 避免在 UPDATE 语句中多次调用标量函数

sql - 索引 View 在没有索引的情况下编写脚本