Mysql查询对数老化

时间:2012-10-11 22:46:11

标签: mysql

我想基于老化实现'对数'分数衰减,我想弄清楚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。

enter image description here

我并不真正关心WHERE clausule;这很简单。我想弄清楚的是对数老化部分。

3 个答案:

答案 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')

Matlab output

答案 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

enter image description here

希望它可以提供帮助!