我有2个MYSQL表,用户和分数。详细信息:
我的目的是获得20个用户列表,这些用户具有点域排序DESC(降序)和平均时间域排序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
我尝试了很多次不同的查询,但结果仍然是错误的。你能给我一些解决方案吗?
提前谢谢!
@德拉普是个天才。我一直不明白他是如何编写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而不是user@变量,可以得到相同的结果。
我想你错过了对餐桌关系的理解...
用户:分数=1:*
只是加入
不是一个解决方案。
这是你的意图吗?
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 point, asc获取每个用户的平均值和平均值avg_time)avg_time
如果你想得到每个分数的排名?使用左外连接
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
好的,我想我现在明白你想要什么了,让我在查询前澄清一下。你想要每个用户有1条记录。对于每个用户,你想要他们的最佳积分记录。在每个用户的最佳积分中,你想要平均时间最好的。一旦你有了所有用户的“最佳”值,你希望最终结果首先以最佳积分排序......几乎就像比赛的排名一样。
现在是查询。如果上面的语句是准确的,你需要从获得每个人的最佳点/平均时间开始,并为该条目分配一个“排名”。这很容易使用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
由SQLFiddle处理的结果
注意,由于需要内联@variables来获得答案,因此每行末尾都有两个额外的列。这些只是“遗留下来的”,在任何实际的输出演示中都可以忽略。。。或者,您可以将整个内容包装到一个更高的级别上,只获得您想要的几个列
select
PQ.UserName,
PQ.Point,
PQ.Avg_Time
from
( entire query above pasted here ) as PQ
问题内容: 在MS SQL Server 2008 R2中编写存储过程,我想避免使用DSQL … 我希望有条件的排序方法(ASC或DESC)。 现在,对于一个数字列,我将只使用一个case语句并取反该值以模拟ASC或DESC …即: 用alpha列执行此操作的合适方法是什么? 编辑:我想到了一个聪明的方法,但似乎效率很低…我可以使用自动编号将有序的alpha列插入到临时表中,然后使用上述方法按自动
问题内容: 我需要按日期/时间字段(例如)升序对PostgreSQL表进行排序last_updated。 但是,该字段允许为空或空,我想与空记录之前,非空。 这可能吗? 问题答案: 为该ORDER BY子句提供了关键字,以完全满足该需求: 一个典型的用例是使用降序排序(DESC),它会生成默认的升序(ASC)的完整反转,首先是空值。通常不理想-因此,将null值保持在最后: 要支持带有索引的查询,
问题内容: 桌子: 的PHP HTML结果: 任何人都注意到桌上的结果。时代是不正确的顺序? 我改变了另一种方式与ASC / DESC,仍然显示最后一个id_timeslot的时间吗? 预期结果: 问题答案: 您正在对记录进行分组,因此每种情况下您只会看到最后一次。 尝试使用
问题内容: 我了解我可以按如下顺序在sql查询中按顺序使用变量: 但是我也该如何在asc和desc部分中使用变量? 问题答案: 没有每个选项,它的子句例如:
问题内容: 我使用以下SP来对新闻文章列表进行分页。您可能会猜到,是要返回的行数,是从中选择行的索引(按内部查询排序),指示要排序的列,并指示是否对一个方向或另一个方向进行排序。在添加参数之前,我的原始查询在 这里。 现在,实际上没有任何问题,但是参数不起作用。如果提供1作为参数,它将为我提供与提供2作为该参数完全相同的结果。 问题答案: 行号不会在每一行上求值,但是case语句是有效的,因此无论
我有一张日期表 我想按时间顺序点菜。我发现另一个线程推荐使用: 但输出不能正确地将最新的排序为最旧的。