我有2个MYSQL表,用户和得分。详情:
我的目的是获得20个用户列表 point 字段排序DESC(降序)组合 avg_time 字段排序ASC(升序)。我使用查询:
SELECT users.username, scores.point, scores.avg_time
FROM scores, users
WHERE scores.user_id = users.id
GROUP BY users.username
ORDER BY scores.point DESC, scores.avg_time
LIMIT 0, 20
结果是:
结果是错误的,因为第一行恰好是point = 100和avg_time = 60。
我想要的结果是:
username point avg_time
demo123 100 60
demo123456 100 100
demo 90 120
我尝试了多次不同的查询,但结果仍然是错误的。你能给我一些解决方案吗?
提前致谢!
答案 0 :(得分:25)
好的,我认为我理解你现在想要的东西,让我在查询之前澄清确认。您希望每个用户拥有1条记录。对于每个用户,您需要他们的BEST POINTS得分记录。在每个用户的最佳分数中,您希望平均时间最长的分数。一旦你拥有所有用户“最佳”价值,你希望最终结果首先按最佳点排序......几乎就像比赛的排名。
所以现在查询。如果上述陈述是准确的,您需要从获得每个人的最佳点/平均时间开始,并为该条目指定“等级”。使用MySQL @变量很容易做到这一点。然后,只需包含一个HAVING子句,只保留每个人排名为1的记录。最后应用最佳点和最短平均时间的顺序。
select
U.UserName,
PreSortedPerUser.Point,
PreSortedPerUser.Avg_Time,
@UserRank := if( @lastUserID = PreSortedPerUser.User_ID, @UserRank +1, 1 ) FinalRank,
@lastUserID := PreSortedPerUser.User_ID
from
( select
S.user_id,
S.point,
S.avg_time
from
Scores S
order by
S.user_id,
S.point DESC,
S.Avg_Time ) PreSortedPerUser
JOIN Users U
on PreSortedPerUser.user_ID = U.ID,
( select @lastUserID := 0,
@UserRank := 0 ) sqlvars
having
FinalRank = 1
order by
Point Desc,
Avg_Time
Results as handled by SQLFiddle
注意,由于获得答案所需的内联@variables,每行末尾有两个额外的列。这些只是“遗留下来”,可以在您尝试的任何实际输出演示文稿中被忽略...或者,您可以将整个事物包装在一个更多级别上,以获得您想要的几个列
select
PQ.UserName,
PQ.Point,
PQ.Avg_Time
from
( entire query above pasted here ) as PQ
答案 1 :(得分:1)
我想你错过了关于表格的关系..
用户:得分= 1:*
只是join
不是解决方案。
这是你的意图吗?
SELECT users.username, avg(scores.point), avg(scores.avg_time)
FROM scores, users
WHERE scores.user_id = users.id
GROUP BY users.username
ORDER BY avg(scores.point) DESC, avg(scores.avg_time)
LIMIT 0, 20
(此查询通过desc点获取每个用户的平均点和平均avg_time,asc)avg_time
如果你想获得每个分数排名?使用left outer join
SELECT users.username, scores.point, scores.avg_time
FROM scores left outer join users on scores.user_id = users.id
ORDER BY scores.point DESC, scores.avg_time
LIMIT 0, 20
答案 2 :(得分:1)
@DRapp是个天才。我从来不知道他是如何编写SQL的,所以我尝试用自己的理解编写它。
SELECT
f.username,
f.point,
f.avg_time
FROM
(
SELECT
userscores.username,
userscores.point,
userscores.avg_time
FROM
(
SELECT
users.username,
scores.point,
scores.avg_time
FROM
scores
JOIN users
ON scores.user_id = users.id
ORDER BY scores.point DESC
) userscores
ORDER BY
point DESC,
avg_time
) f
GROUP BY f.username
ORDER BY point DESC
使用GROUP BY而不是用户@variables会产生相同的结果。
答案 3 :(得分:0)
默认按pk id排序,所以结果为
用户名点avg_time
demo123 100 90 ---> id = 4
demo123456 100 100 ---> id = 7
demo 90 120 ---> id = 1