如何进行复杂的SQL查询

时间:2016-11-18 22:09:03

标签: php mysql sql sorting

我正在努力建立一个类似的网站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做什么,或者我必须以其他方式做到这一点?

2 个答案:

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