Помогите избежать CURSOR для расчета столбцов - PullRequest
3 голосов
/ 12 мая 2011

У меня есть куча записей в табличной переменной, например:

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 - это Product . Ранг - это значение, которое представляет ранг продукта в данный момент времени. RankCreated - это время, когда Продукт был ранжирован.

Что я пытаюсь сделать:

Рассчитать "движение" между каждым продуктомранг, для каждого продукта.Где «движение» определяется как текущее - предыдущее.

Таким образом, «вычисляемый столбец» будет выглядеть так:

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 секунд, что недопустимо.

Кто-нибудь может помочь?

1 Ответ

4 голосов
/ 12 мая 2011
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
...