我正在努力建立一个类似的网站Hacker News,我发现这个算法需要帮助我对我网站上的链接进行排序,这里是:
Score = (P-1) / (T+2)^G
where,
P = points of an item (and -1 is to negate submitters vote)
T = time since submission (in hours)
G = Gravity, defaults to 1.8 in news.arc
所以我需要创建一个SQL查询,它将使用上面的等式对数据进行排序,但我不知道如何做到这一点。这是我的表结构:
Table 1 name: links
Table 1 fields: id, title, url, user_id, created_at
Table 2 name: votes
Table 2 fields: id, user_id, link_id, vote, created_at
表2中的表决可以是三个值中的一个:1,0,-1
那么甚至可以用SQL做什么,或者我必须以其他方式做到这一点?
答案 0 :(得分:2)
如果您想使用仅SQL方法。
首先让每个参数与表中的候选者一起映射:
P
votes
表中投票列的总和。
T
当前日期 - now()
功能 - 减去links
表中的 created_at 列。
G
常数。
考虑到这一点,以下SQL select语句应返回每个链接的分数。
select links.id, (sum(vote) - 1) / POWER(DATEDIFF(now(),links.created_at)*24 + 2, 1.8)
from links, votes
where links.id = votes.link_id
group by links.id
sum(vote)
==> P
DATEDIFF(now(),links.created_at)*24
==> T
。
1.8
==> G
答案 1 :(得分:1)
加入两个表,并使用SUM()
获得投票数。我在加入时使用v.user_id != l.user_id
对提交者的投票进行了折扣。
您可以使用SUBTIME()
获取T
。
SELECT l.*, IFNULL(SUM(v.vote), 0) AS votes
FROM links AS l
LEFT JOIN votes AS v ON v.link_id = l.id AND v.user_id != l.user_id
GROUP BY l.id
ORDER BY votes / POWER(SUBTIME(NOW(), l.created_at), 1.8)
要修复错误,请在子查询中进行分组并在外部查询中进行排序。
SELECT * FROM (
SELECT l.*, IFNULL(SUM(v.vote), 0) AS votes
FROM links AS l
LEFT JOIN votes AS v ON v.link_id = l.id AND v.user_id != l.user_id
GROUP BY l.id
) AS x
ORDER BY votes / POWER(SUBTIME(NOW(), l.created_at), 1.8)