mysql - 在另一个表中按行排序以填充 "What' s Hot"list

标签 mysql sorting

我有两个表,是这样创建的(只显示相关信息)

CREATE TABLE levels
(
    id INT(6) UNSIGNED AUTO_INCREMENT,
    gameid INT(6),
    created DATETIME,
    PRIMARY KEY(id,gameid)
)

CREATE TABLE votes
(
    levelid INT(6) NOT NULL REFERENCES levels(id),
    vote TINYINT(1),
    date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY(levelid)
)

用户可以对级别进行投票(+1 或 -1),从而创建指向某个级别的投票记录。

我想对数据做的是这样的,在非语法中:

SELECT * FROM levels ORDER BY
(select sum(vote) from votes where votes.levelid=levels.id and date is within the last week)

我怎样才能把它变成合法的 mySQL 查询?我尝试的每件事都给我一个非常神秘的错误消息(“出了点问题!检查手册!”)而且我只是 mySQL 的高级初学者。

目标是返回我所有的关卡,按照上周投票总和最高的人排序...这样新的关卡就会继续前进,而旧的关卡就会消失。

提前致谢!

编辑:

下面是预期结果的示例: 这是我的数据(为清楚起见,以英文呈现):

级别:
LEVEL1 (id=1)
级别 2 (id=2)

票数:
两天前为 LEVEL1 +1
+1 十天前的 LEVEL1
二十天前为 LEVEL1 +1
一天前为 LEVEL2 +1
三天前为 LEVEL2 +1
-1 三十天前的 LEVEL2

所以我可以这样查询:

SELECT * FROM LEVELS ORDER BY (select sum(vote) from votes where levelid=levels.id) 

这让我的 LEVEL1 +3,LEVEL2 +1。

但是,在过去的 7 天内,我应该看到 LEVEL1 +1,LEVEL2 +2,因此首先返回 LEVEL2。

此外,我普遍认为“按(选择...)排序”会很慢。

再进行一次编辑:

此查询有效:

SELECT * FROM levels ORDER BY (SELECT SUM(vote) FROM votes WHERE levelid=levels.id AND votes.date>=( CURDATE() - INTERVAL 7 DAY )) DESC

...但这是做这类事情的最佳方式吗?

最佳答案

您可以使用左连接来做到这一点:

SELECT levels.*, coalesce(sum(votes.vote),0) as total_vote
FROM levels 
LEFT JOIN votes ON votes.levelid = levels.id
WHERE votes.date >=( CURDATE() - INTERVAL 7 DAY ))
GROUP BY levels.id
ORDER BY coalesce(sum(votes.vote),0) desc;

此处的合并确保尚未投票的级别获得分数(而不是空值)并正确排序。

关于mysql - 在另一个表中按行排序以填充 "What' s Hot"list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34362244/

相关文章:

php - 相当于 mysql 和 eloquent 查询生成器

mysql - 使用 Dockerfile 设置 MySQL

java - 使用比较器对列表列表进行排序

algorithm - 哪种排序算法更快?

string - 如何根据另一个字符串表定义的顺序对一个字符串表进行排序(Lua)

javascript - 使用函数按值对 JavaScript 对象进行排序

mysql - 从表中获取列名称,其中值为零

php - 我怎样才能结合 2 个复杂的 mysql 查询

mysql - 修复编码

python - 使用类定义的计算对列表进行排序