我有一个SQL问题。首先,我想知道只有SQL才有可能,如果没有,有人知道一个好的解决方法。
我们正在建立一个网站,用户可以在该网站上投票支持视频 用户可以在Facebook身份验证后通过短信或直接在网站上投票 我们必须列出所有视频的最高列表,并计算每个视频列表的“位置”。
到目前为止,我们已经使用一个简单的子查询来做到这一点,如下所示:
SELECT v.video_id AS id,
(SELECT (COUNT(*)+1) FROM videos AS v2
WHERE (v2.SMS_votes + v2.facebook_votes) > (v.SMS_votes + v.facebook_votes)) AS total_position
FROM videos AS v
SMS_votes
和facebook_votes
是汇总字段。每种投票都有单独的表格,每张投票都有记录,包括投票时间。
这很好用,计算位置......如果两个或多个视频的票数相同,他们会“分享”这个位置。
不幸的是,没有位置共享,我们必须通过以下规则解决它:
是否可以仅在SQL中执行此类递归排序,还是必须在代码中手动解决此问题?欢迎所有想法。需要注意的是,性能在这里很重要,因为顶部列表在整个站点中使用。
答案 0 :(得分:0)
我认为通过重复计算(可能无限制)执行此类排序是不可行的,但如果您愿意限制回顾的时间,可以采取一些方法
这是一种可能性。
SELECT video_id,
SMS_votes + facebook_votes AS total_votes,
SMS_votes,
COUNT(CASE WHEN time > NOW() - INTERVAL 1 HOUR THEN 1 END) AS h1,
COUNT(CASE WHEN time > NOW() - INTERVAL 2 HOUR THEN 1 END) AS h2,
COUNT(CASE WHEN time > NOW() - INTERVAL 3 HOUR THEN 1 END) AS h3
FROM videos
JOIN SMS_votes USING(video_id)
GROUP BY video_id
ORDER BY total_votes DESC, SMS_votes DESC, h1 DESC, h2 DESC, h3 DESC;
这假设您有一个名为 SMS_votes 的表格跟踪每个投票,并带有 video_id 字段和时间字段。
对于每个视频,它计算总票数,短信投票,过去一小时,过去两小时和过去三小时的短信投票。然后,它会对所有这些值执行ORDER BY
以获得正确的位置。
将此扩展包含更广泛的小时数相当容易,但您可能还需要考虑使用越来越长的时间范围。例如,您首先查看过去一小时,过去一天,过去一周等的投票。我怀疑这会降低您拥有相同投票的视频的机会,而无需添加额外的计算。