通过考虑时间衰减因子使用其他两列计算新列
Calculating a new column using two other columns by considering time decaying factor
我的问题有点棘手,如果有人帮助我,我将不胜感激。
我有以下 table ,我想根据用户在之前比赛中获得的分数计算最后一列(当前比赛前的智力资本)。分数随时间衰减,公式如下:
得分*e^(-t/500)
t 是距离上一场比赛已经过去的天数。如果用户在当前比赛之前参加了不止一场比赛,我们会添加分数。
以下table说明了我要计算的内容。
competitionsId UserId date score intellectual-capital-prior-to-current
1 100 1/1/2015 3000
1 200 1/1/2015 3000
1 300 1/1/2015 3000
1 400 1/1/2015 3000
2 100 1/5/2015 4000 3000* POWER(e, -4/500)
2 400 1/5/2015 4000 3000* POWER(e, -4/500)
3 100 1/10/2015 1200 3000* POWER(e,-9/500)+ 4000*POWER(e,-5/500)
3 300 1/10/2015 1200 3000*POWER(e,-9/500)
3 400 1/10/2015 1200 3000* POWER(e, -9/500) + 4000*POWER(e,-5/500)
4 200 1/20/2015 1000 3000*POWER(e,-19/500)
4 300 1/20/2015 1000 3000*POWER(e,-19/500)+ 1200*POWER(e,-10/500)
例如,在比赛 3 之前,用户 100 参加了比赛 2 和比赛 1。她在比赛 1 中的分数是 3000,因此考虑衰减因子,我们有 3000*e^(-9/500) 和她在比赛中的分数2 是 4000,所以考虑到衰减因子,我们有 4000*e^(-5/500)。因此 user100 在比赛 3 中的智力资本为:3000*e^(-9/500) + 4000*e^(-5/500)
以下内容可能会帮助您得出想要的计算结果。我不完全确定 e
在您的公式中代表什么,但是使用一些 window 函数我们可以获得所需的先前值并累积值。
DEMO at SQL Fiddle(MS SQL Server 2014 架构设置)
CREATE TABLE Table1
([competitionsId] int, [UserId] int, [date] datetime, [score] int, [note] varchar(45))
;
INSERT INTO Table1
([competitionsId], [UserId], [date], [score], [note])
VALUES
(1, 100, '2015-01-01 00:00:00', 3000, '-'),
(1, 200, '2015-01-01 00:00:00', 3000, '-'),
(1, 300, '2015-01-01 00:00:00', 3000, '-'),
(1, 400, '2015-01-01 00:00:00', 3000, '-'),
(2, 100, '2015-01-05 00:00:00', 4000, '3000* POWER(e, -4/500)'),
(2, 400, '2015-01-05 00:00:00', 4000, '3000* POWER(e, -4/500)'),
(3, 100, '2015-01-10 00:00:00', 1200, '3000* POWER(e,-9/500)+ 4000*POWER(e,-5/500)'),
(3, 300, '2015-01-10 00:00:00', 1200, '3000*POWER(e,-9/500)'),
(3, 400, '2015-01-10 00:00:00', 1200, '3000* POWER(e, -9/500) + 4000*POWER(e,-5/500)'),
(4, 200, '2015-01-20 00:00:00', 1000, '3000*POWER(e,-19/500)'),
(4, 300, '2015-01-20 00:00:00', 1000, '3000*POWER(e,-19/500)+ 1200*POWER(e,-10/500)')
;
查询 1:
with Primo as (
select
*
, datediff(day,lead([date],1) over(partition by userid order by [date]),[date]) day_diff
from Table1
)
, Secondo as (
select
*
, lag(day_diff,1) over(partition by userid order by [date]) t
, lag(score,1) over(partition by userid order by [date]) prev_score
from primo
)
select
power(prev_score*1.0,t/500.0) x
, sum(power(prev_score*1.0,t/500.0)) over(partition by userid order by [date]) y
, competitionsId,UserId,date,score,day_diff,t,prev_score,note
from secondo
;
| x | y | competitionsId | UserId | date | score | day_diff | t | prev_score | note |
|--------|--------|----------------|--------|----------------------|-------|----------|--------|------------|-----------------------------------------------|
| (null) | (null) | 1 | 100 | 2015-01-01T00:00:00Z | 3000 | -4 | (null) | (null) | - |
| 0.9 | 0.9 | 2 | 100 | 2015-01-05T00:00:00Z | 4000 | -5 | -4 | 3000 | 3000* POWER(e, -4/500) |
| 0.9 | 1.8 | 3 | 100 | 2015-01-10T00:00:00Z | 1200 | (null) | -5 | 4000 | 3000* POWER(e,-9/500)+ 4000*POWER(e,-5/500) |
| (null) | (null) | 1 | 200 | 2015-01-01T00:00:00Z | 3000 | -19 | (null) | (null) | - |
| 0.7 | 0.7 | 4 | 200 | 2015-01-20T00:00:00Z | 1000 | (null) | -19 | 3000 | 3000*POWER(e,-19/500) |
| (null) | (null) | 1 | 300 | 2015-01-01T00:00:00Z | 3000 | -9 | (null) | (null) | - |
| 0.9 | 0.9 | 3 | 300 | 2015-01-10T00:00:00Z | 1200 | -10 | -9 | 3000 | 3000*POWER(e,-9/500) |
| 0.9 | 1.8 | 4 | 300 | 2015-01-20T00:00:00Z | 1000 | (null) | -10 | 1200 | 3000*POWER(e,-19/500)+ 1200*POWER(e,-10/500) |
| (null) | (null) | 1 | 400 | 2015-01-01T00:00:00Z | 3000 | -4 | (null) | (null) | - |
| 0.9 | 0.9 | 2 | 400 | 2015-01-05T00:00:00Z | 4000 | -5 | -4 | 3000 | 3000* POWER(e, -4/500) |
| 0.9 | 1.8 | 3 | 400 | 2015-01-10T00:00:00Z | 1200 | (null) | -5 | 4000 | 3000* POWER(e, -9/500) + 4000*POWER(e,-5/500) |
我的问题有点棘手,如果有人帮助我,我将不胜感激。
我有以下 table ,我想根据用户在之前比赛中获得的分数计算最后一列(当前比赛前的智力资本)。分数随时间衰减,公式如下:
得分*e^(-t/500)
t 是距离上一场比赛已经过去的天数。如果用户在当前比赛之前参加了不止一场比赛,我们会添加分数。
以下table说明了我要计算的内容。
competitionsId UserId date score intellectual-capital-prior-to-current
1 100 1/1/2015 3000
1 200 1/1/2015 3000
1 300 1/1/2015 3000
1 400 1/1/2015 3000
2 100 1/5/2015 4000 3000* POWER(e, -4/500)
2 400 1/5/2015 4000 3000* POWER(e, -4/500)
3 100 1/10/2015 1200 3000* POWER(e,-9/500)+ 4000*POWER(e,-5/500)
3 300 1/10/2015 1200 3000*POWER(e,-9/500)
3 400 1/10/2015 1200 3000* POWER(e, -9/500) + 4000*POWER(e,-5/500)
4 200 1/20/2015 1000 3000*POWER(e,-19/500)
4 300 1/20/2015 1000 3000*POWER(e,-19/500)+ 1200*POWER(e,-10/500)
例如,在比赛 3 之前,用户 100 参加了比赛 2 和比赛 1。她在比赛 1 中的分数是 3000,因此考虑衰减因子,我们有 3000*e^(-9/500) 和她在比赛中的分数2 是 4000,所以考虑到衰减因子,我们有 4000*e^(-5/500)。因此 user100 在比赛 3 中的智力资本为:3000*e^(-9/500) + 4000*e^(-5/500)
以下内容可能会帮助您得出想要的计算结果。我不完全确定 e
在您的公式中代表什么,但是使用一些 window 函数我们可以获得所需的先前值并累积值。
DEMO at SQL Fiddle(MS SQL Server 2014 架构设置)
CREATE TABLE Table1
([competitionsId] int, [UserId] int, [date] datetime, [score] int, [note] varchar(45))
;
INSERT INTO Table1
([competitionsId], [UserId], [date], [score], [note])
VALUES
(1, 100, '2015-01-01 00:00:00', 3000, '-'),
(1, 200, '2015-01-01 00:00:00', 3000, '-'),
(1, 300, '2015-01-01 00:00:00', 3000, '-'),
(1, 400, '2015-01-01 00:00:00', 3000, '-'),
(2, 100, '2015-01-05 00:00:00', 4000, '3000* POWER(e, -4/500)'),
(2, 400, '2015-01-05 00:00:00', 4000, '3000* POWER(e, -4/500)'),
(3, 100, '2015-01-10 00:00:00', 1200, '3000* POWER(e,-9/500)+ 4000*POWER(e,-5/500)'),
(3, 300, '2015-01-10 00:00:00', 1200, '3000*POWER(e,-9/500)'),
(3, 400, '2015-01-10 00:00:00', 1200, '3000* POWER(e, -9/500) + 4000*POWER(e,-5/500)'),
(4, 200, '2015-01-20 00:00:00', 1000, '3000*POWER(e,-19/500)'),
(4, 300, '2015-01-20 00:00:00', 1000, '3000*POWER(e,-19/500)+ 1200*POWER(e,-10/500)')
;
查询 1:
with Primo as (
select
*
, datediff(day,lead([date],1) over(partition by userid order by [date]),[date]) day_diff
from Table1
)
, Secondo as (
select
*
, lag(day_diff,1) over(partition by userid order by [date]) t
, lag(score,1) over(partition by userid order by [date]) prev_score
from primo
)
select
power(prev_score*1.0,t/500.0) x
, sum(power(prev_score*1.0,t/500.0)) over(partition by userid order by [date]) y
, competitionsId,UserId,date,score,day_diff,t,prev_score,note
from secondo
;
| x | y | competitionsId | UserId | date | score | day_diff | t | prev_score | note |
|--------|--------|----------------|--------|----------------------|-------|----------|--------|------------|-----------------------------------------------|
| (null) | (null) | 1 | 100 | 2015-01-01T00:00:00Z | 3000 | -4 | (null) | (null) | - |
| 0.9 | 0.9 | 2 | 100 | 2015-01-05T00:00:00Z | 4000 | -5 | -4 | 3000 | 3000* POWER(e, -4/500) |
| 0.9 | 1.8 | 3 | 100 | 2015-01-10T00:00:00Z | 1200 | (null) | -5 | 4000 | 3000* POWER(e,-9/500)+ 4000*POWER(e,-5/500) |
| (null) | (null) | 1 | 200 | 2015-01-01T00:00:00Z | 3000 | -19 | (null) | (null) | - |
| 0.7 | 0.7 | 4 | 200 | 2015-01-20T00:00:00Z | 1000 | (null) | -19 | 3000 | 3000*POWER(e,-19/500) |
| (null) | (null) | 1 | 300 | 2015-01-01T00:00:00Z | 3000 | -9 | (null) | (null) | - |
| 0.9 | 0.9 | 3 | 300 | 2015-01-10T00:00:00Z | 1200 | -10 | -9 | 3000 | 3000*POWER(e,-9/500) |
| 0.9 | 1.8 | 4 | 300 | 2015-01-20T00:00:00Z | 1000 | (null) | -10 | 1200 | 3000*POWER(e,-19/500)+ 1200*POWER(e,-10/500) |
| (null) | (null) | 1 | 400 | 2015-01-01T00:00:00Z | 3000 | -4 | (null) | (null) | - |
| 0.9 | 0.9 | 2 | 400 | 2015-01-05T00:00:00Z | 4000 | -5 | -4 | 3000 | 3000* POWER(e, -4/500) |
| 0.9 | 1.8 | 3 | 400 | 2015-01-10T00:00:00Z | 1200 | (null) | -5 | 4000 | 3000* POWER(e, -9/500) + 4000*POWER(e,-5/500) |