我想基于老化实现'对数'分数衰减,我想弄清楚SUM / LOG组合。这里有一个当前查询的简化版本:
SELECT SUM(1) as total_score FROM posts
JOIN votes ON votes.post_id = posts.post_id
WHERE 1
GROUP BY post_id
ORDER BY total_score DESC
我目前正在使用SELECT'SUM(1)作为total_score',但我想修改查询以考虑投票的日期/年龄;今天投票从今天权重1,投票从15天前的权重接近.8和投票从30天前接近0.我将日期字段存储在投票表(vote_date)上作为unix_timestamp。
我并不真正关心WHERE clausule;这很简单。我想弄清楚的是对数老化部分。
答案 0 :(得分:2)
我认为你的答案分为两部分。首先是加权函数,然后是SQL实现。
Wegighting功能:
根据你的图表,你不希望日志权重相当于抛物线。
由此你必须解决
Xc = y
,其中
X = [1 1 1 ;
15^2 15 1;
30^2 30 1];
和
y = [1;.8;0];
你得到c = X ^( - 1)y或在matlab中
c = X\y
现在你有了所描述的二次函数的适当的wieights;即y = ax ^ 2 + bx + c,(a,b,c)=( - 。0013,.0073,.9941)。
SQL部分:
你选择语句应该是这样的(假设感兴趣的列被命名为“年龄”)
SELECT (-.0013*age*age + .0073*age + .9941) as age_weighted
希望有所帮助
干杯
这是完整的Matlab代码(也是双重检查解决方案)
X = [1 1 1 ;
15^2 15 1;
30^2 30 1];
y = [1;.8;0];
c = X\y;
x= (1:30)';
y = [x.^2 x ones(30,1)]*c;
figure(1)
clf;hold on
plot(x,y)
plot([1 15 30],[1 .8 0],'o')
答案 1 :(得分:0)
假设您有一个函数WEIGHT(age)
,它给出了age
天之前投票的权重。
然后你的查询将是
SELECT SUM(WEIGHT(DATEDIFF(CURRENT_DATE, votes.date_vote_cast))) as total_score,
posts.post_id
FROM posts
JOIN votes ON votes.post_id = posts.post_id
WHERE votes.date_vote_cast <= CURRENT_DATE
AND votes.date_vote_cast > CURRENT_DATE - INTERVAL 30 DAY
GROUP BY post_id
ORDER BY total_score DESC
我恐怕我不确切地知道你想要WEIGHT(age)
的功能。但你这样做,你可以解决它。
答案 2 :(得分:0)
我没有完成SQL部分,但是我发现了一个能够提供你所追求的衰变的函数,至少在数学上是
y=(sqrt(900-(x^2)))/30
或在你的情况下
score=(sqrt(900-(days^2)))/30
希望它可以提供帮助!