SQL SELECT 使用 MIN() 和 GROUP BY 时未按预期运行
SQL SELECT not behaving as expected when using MIN() and GROUP BY
我有一个简单的在线排行榜,它也在字符串中对重播进行编码。尽管排行榜存储了(当前)报告的每个单圈时间,检索 php 只是 returns 每个独特玩家的最佳时间,因此:
SELECT driver
, MIN(time)
, track
, replay
FROM Laptimes
WHERE track = '$track'
GROUP
BY driver
ORDER
BY MIN(time) ASC
LIMIT 10
这会正确报告最快单圈时间,但不会 select 与该单圈时间相关的回放。
相反,您只会收到为该车手提交的第一个重播。
我 100% 确定回放已正确存储在数据库中,因为如果我删除 MIN(),我会得到每个玩家的每圈时间,并且可以毫无问题地观看每个回放。
我似乎无法说服 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)
请注意,正如 JNevill 所说,您的原始查询不是有效的标准 SQL,因为 select
和 group by
子句不一致。 MySQL 可能会容忍它(如果您禁用选项 ONLY_FULL_GROUP_BY
,这是旧版本中的默认设置),但是您会在 non-aggregated 列中得到任意值,这些值不存在于 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:使用准备好的语句!不要将参数混合到查询字符串中 - 这既低效又不安全。
我有一个简单的在线排行榜,它也在字符串中对重播进行编码。尽管排行榜存储了(当前)报告的每个单圈时间,检索 php 只是 returns 每个独特玩家的最佳时间,因此:
SELECT driver
, MIN(time)
, track
, replay
FROM Laptimes
WHERE track = '$track'
GROUP
BY driver
ORDER
BY MIN(time) ASC
LIMIT 10
这会正确报告最快单圈时间,但不会 select 与该单圈时间相关的回放。
相反,您只会收到为该车手提交的第一个重播。
我 100% 确定回放已正确存储在数据库中,因为如果我删除 MIN(),我会得到每个玩家的每圈时间,并且可以毫无问题地观看每个回放。
我似乎无法说服 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)
请注意,正如 JNevill 所说,您的原始查询不是有效的标准 SQL,因为 select
和 group by
子句不一致。 MySQL 可能会容忍它(如果您禁用选项 ONLY_FULL_GROUP_BY
,这是旧版本中的默认设置),但是您会在 non-aggregated 列中得到任意值,这些值不存在于 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:使用准备好的语句!不要将参数混合到查询字符串中 - 这既低效又不安全。