我使用了这个查询,我觉得mysql服务器崩溃了什么。现在无法到达。这是巧合还是我的查询太糟糕了?如果不好我该怎么办呢
处理400.000行2个表一个是得分列表而另一个是用户
SELECT a.*
from
(
SELECT @curRank := @curRank +1 AS ROW , s.UserId,
s.AverageScore As Score, u.UserName
FROM scorelisting s, (SELECT @curRank :=0) r, Users u
where u.UserId=s.UserId
order by AverageScore desc
) a
where UserId = 95890
答案 0 :(得分:2)
我不知道我是否过度简化了这一点,但是......如果您正在寻找特定用户在其他人中的排名,我会找出该人的“averageScore”是什么,然后获得所有记录的COUNT(*),其平均值比你想要的平均值更高,然后得到那个人的名字......有意义吗?然后尝试以下方法。
<强> REVISED AND TESTED -- SQL FIDDLE 强> SQLFiddle上的示例分别为用户a-f和averageScores为10-60的6个条目。查询选择用户3(avgScore),因此有3(d,e和f)具有更高的平均值(40,50,60),这将用户'c'(id 3)放在第4位。
SELECT
u.UserName,
PreQuery.AverageHigherThanYou +1 as UserRank
from
users u,
( select
COUNT(*) as AverageHigherThanYou
from
scoreListing s,
( select @MyAvg := s2.AverageScore
from scoreListing s2
where s2.UserID = 95890 ) sqlvars
where
s.AverageScore > @MyAvg ) PreQuery
where
u.userid = 95890
“PreQuery”只会为您的特定用户获取除静态加入到scoreListing之外的所有内容,并将其放入单个列值。
然后逗号Users表(旧的ANSI,没有连接条件)将始终返回一条记录...然后,仅在USER表上应用WHERE子句,以便一个人获取其名称信息。
现在,如果您想要有多少是高,平均或更低,您可以调整查询类似
( SELECT
sum( if( s.averageScore < s2.averageScore, 1, 0 )) as LowerAverageThanYou,
sum( if( s.averageScore = s2.averageScore, 1, 0 )) as SameAverageAsYou,
sum( if( s.averageScore > s2.averageScore, 1, 0 )) as HigherAverageThanYou
from
scoreListing s
join scoreListing s2
ON s2.UserID = 95890 ) PreQuery,
你显然必须等到你的机器被释放后再试一次。
我还会在scoreListing表上有两个索引。一个只是ID跳转到UserID = 95890记录,用于比较该人的平均值,另一个记录在averageScore上,所以如果你只做了那么高,你的WHERE子句只需扫描那些记录而不是整个400,000记录。