【发布时间】:2012-01-28 03:25:05
【问题描述】:
给定一个获得的用户积分表,我需要计算获得的累积积分的六个月半衰期。也就是说,在过去 6 个月内获得的所有积分都以 100% 的价值计算,6-12 个月的价值为 50%,12-18 个月的 %25 等。
这是我使用 CTE 的最佳尝试:
DECLARE @t AS TABLE (
ID int NOT NULL,
DT SMALLDATETIME NOT NULL,
POINTS int NOT NULL,
UserId INT NOT null,
POINTS_TOTAL INT NOT NULL)
INSERT INTO @t
VALUES (1, '1/1/2010', 20, 1, 20)
,(5, '7/1/2010', 30, 1, 50)
,(7, '1/1/2011', 10, 1, 60)
,(8, '7/1/2011', 15, 1, 75)
,(9, '12/25/2011', 15, 1, 90)
;WITH ctePts AS
(SELECT t.*, POINTS AS Decay
FROM @t AS t
WHERE t.DT > DATEADD(mm, 6, GETUTCDATE())
UNION ALL
SELECT t.ID, t.DT, t.POINTS, t.UserId, t.POINTS_TOTAL, CAST(ctePts.Decay * 0.5 + t.POINTS AS INT) AS Decay
FROM ctePts
INNER JOIN @t AS t
ON t.UserId = ctePts.UserId
AND t.DT <= ctePts.DT AND t.DT > DATEADD(mm, 6, ctePts.DT)
)
SELECT *
FROM ctePts
决赛桌将有一个 HALF_LIFE 列,其中包含该用户获得的所有积分的调整总和。我应该能够运行以下查询来获取用户在任何给定时间点的当前积分状态(根据半衰期衰减调整的总积分):
SELECT UserIdInt, POINTS, POINTS_HALFLIFE FROM
(SELECT UserIdInt,
ISNULL(p.POINTS_TOTAL,0) AS POINTS, ISNULL(p.POINTS_HALFLIFE,0) POINTS_HALFLIFE,
ROW_NUMBER() OVER (Partition BY UserIdInt ORDER BY p.ID DESC) AS rownum
FROM dbo.USER_POINTS p ) a
WHERE rownum = 1
【问题讨论】:
标签: sql-server-2008 tsql user-defined-functions