使用MIN()和GROUP BY时,SQL SELECT的行为未达到预期



我有一个简单的在线排行榜,它还将重播编码为字符串。尽管排行榜存储了(目前(报告的每个laptime,但检索php只返回每个唯一玩家的最佳时间,因此:

SELECT driver
, MIN(time)
, track
, replay 
FROM Laptimes 
WHERE track = '$track'
GROUP 
BY driver 
ORDER 
BY MIN(time) ASC 
LIMIT 10

这会正确报告最快的重叠时间,但不会选择与该重叠时间相关的重播。

相反,您只需要为该驱动程序提交第一次重播。

我100%确信回放正确地存储在数据库中,因为如果我删除MIN((,我会得到每个玩家的每个laptime,并且可以毫无问题地观看每个回放。

我似乎无法说服SQL给我与最短延迟时间相关的重播。

您需要整行,因此需要筛选而不是聚合。一个简单的方法使用相关的子查询:

select l.*
from laptimes l
where
track = ? 
l.time = (select min(l1.time) from laptimes l1 where l1.driver = l.driver and l1.track = l.track)

请注意,正如JNevil所评论的,您的原始查询不是有效的标准SQL,因为selectgroup by子句不一致。MySQL可能会容忍它(如果您禁用了选项ONLY_FULL_GROUP_BY,这是旧版本中的默认选项(,但随后您会在group by子句中不存在的非聚合列中获得任意值。当查询按如下方式编写时,这可能更容易理解(这相当于您的原始代码,并且是有效的MySQL代码(:

SELECT driver, MIN(time), ANY_VALUE(track), ANY_VALUE(replay) 
FROM Laptimes 
WHERE (track='$track') 
GROUP BY driver 
ORDER BY MIN(time) ASC LIMIT 10

注2:使用事先准备好的语句!不要在查询字符串中包含参数——这既低效又不安全。

最新更新