SQL查询没有正确排序

时间:2013-03-08 13:16:34

标签: php mysql sql

我有一个人们提交测试的测试,然后提交他们用来完成测试的秒数。

这是查询:

SELECT *
FROM namethatchampion_stats
GROUP BY user
ORDER BY seconds ASC
LIMIT 100

这是表结构:

id | user | seconds | time

我希望我的用户能够多次提交测试,但这仅在他第一次提交时列出。因此,如果用户获得更好的时间,他发布的秒时间将不会在数据库中使用该行,它将仅使用用户发布的第一行。

4 个答案:

答案 0 :(得分:2)

我建议尽可能避免MySQL提供的隐式分组,我的意思是你的查询允许你选择IDTimeseconds,即使他们不包含在聚合函数或group by子句中。

在此声明中:

SELECT  *
FROM    namethatchampion_stats
GROUP BY User
ORDER BY Seconds

你说为每个用户给我一行(随机),然后按秒订购这些随机行,所以即使你有订单,这也不会影响分组:

MySQL Docs

服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的。此外,添加ORDER BY子句不会影响每个组中值的选择。

除非您的列从聚合中排除,并且group by在功能上依赖于组中包含的列(例如主键),否则使用显式分组。在您的方案中,您可以使用表格中的所有行:

SELECT  stat.ID,
        stat.User,
        stat.Seconds,
        stat.Time
FROM    NamethatChampion_stats Stat
        INNER JOIN
        (   SELECT  User, MIN(Seconds) AS Seconds
            FROM    NamethatChampion_stats
            GROUP BY User
        ) MaxStat
            ON MaxStat.User = stat.User
            AND MaxStat.Seconds = stat.Seconds
ORDER BY Seconds ASC
LIMIT 100

<强> Example on SQL Fiddle

上述方法的缺点是,如果用户有2条具有相同最快时间的记录,则两者都将被返回。需要进一步聚合以删除这些重复项(您可能需要通过相同分数的第一次或最后一次测试来限制)。

答案 1 :(得分:1)

我假设你想要每个学生的最佳成绩 - 而且你最喜欢的是MIN(seconds)。如果这是你想要的,这就是方法:

SELECT user, MIN(seconds) AS best_score
FROM namethatchampion_stats
GROUP BY user
ORDER BY best_score ASC
    LIMIT 100 ;

答案 2 :(得分:0)

您的ORDER BY声明应该使用time列,其中包含提交测试的日期,而不是seconds。 (假设它包含一个完整的日期。如果它只是时间,那么这就会超出窗口。)

答案 3 :(得分:0)

这将为每位用户提供最快的时间:

SELECT user, MIN(seconds) 
FROM namethatchampion_stats
GROUP BY user 
LIMIT 100;

这是你想要的吗?