我有一个记录用户在游戏中得分的表格(用户可以提交 5、10、20,他想要的分数是多少)。 我需要显示游戏的 20 个最高分,但每个用户。 (因为用户可能已经提交了例如根据其他用户的分数最高的 4 个分数) 我写的查询是:
SELECT DISTINCT
`table_highscores`.`userkey`,
max(`table_highscores`.`score`),
`table_users`.`username`,
`table_highscores`.`dateachieved`
FROM
`table_highscores`, `table_users`
WHERE
`table_highscores`.`userkey` = `table_users`.`userkey`
AND
`table_highscores`.`gamekey` = $gamekey
GROUP BY
`userkey`
ORDER BY
max(`table_highscores`.`score`) DESC,
LIMIT 0, 20;
输出结果没问题,但是有问题。当我计算天数差异时(今天 - 这 dateachieved
)结果是错误的。 (例如,不是说“分数是 22 天前提交的,而是 43 天前提交的)所以,我必须对每个分数进行第二次查询,以便找到真实日期(意味着 +20 次查询)。有没有更短的方法找到正确的日期?
谢谢。
最佳答案
there is a problem. When i calculate the difference of days (today-this of dateachieved) the result is wrong.
有两个问题
dateachieved
不太可能是与高分相关的值- 你可以使用MySQL's DATEDIFF返回当前日期和
dateachieved
值之间的天数。
使用:
SELECT u.username,
hs.userkey,
hs.score,
DATEDIFF(NOW(), hs.dateachieved)
FROM TABLE_HIGHSCORES hs
JOIN TABLE_USERNAME u ON u.userkey = hs.userkey
JOIN (SELECT ths.userkey,
ths.gamekey,
ths.max_score,
MAX(ths.date_achieved) 'max_date'
FROM TABLE_HIGHSCORES ths
JOIN (SELECT t.userkey,
t.gamekey,
MAX(t.score) 'max_score'
FROM TABLE_HIGHSCORES t
GROUP BY t.userkey, t.gamekey) ms ON ms.userkey = ths.userkey
AND ms.gamekey = ths.gamekey
AND ms.max_score = ths.score
) x ON x.userkey = hs.userkey
AND x.gamekey = hs.gamekey
AND x.max_score = hs.score
AND x.max_date = hs.dateachieved
WHERE hs.gamekey = $gamekey
ORDER BY hs.score DESC
LIMIT 20
我还将您的查询从 ANSI-89 语法更改为使用 ANSI-92 JOIN 语法。它的性能相当,但更易于阅读,语法在 Oracle/SQL Server/Postgres/etc 上受支持,并提供一致的 LEFT JOIN 支持。
另一件事 - 当表和/或列名是 MySQL 关键字时,您只需要使用反引号。
关于SQL 查询有不需要的结果 - 问题出在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1990059/