背景:我是一名业余程序员,试图为赛车游戏创建个人排行榜。这是通过运行MariaDB的Raspberry Pi完成的。排行榜是从另一个站点上刮取并存储在数据库中的。然后,我的个人运动时间会从游戏中通过UDP接收,并存储在Pi的同一MariaDB中。结果显示在php页面上。用户可以在php页面上选择其他汽车并跟踪组合。我想为每个车手组合显示最佳(最低)圈速。 (玩家名称是官方游戏玩家标签,不允许重复。它们都是唯一的。)
使用这样的SELECT语句,我得到了84行,但是得到了所有自己的运行时间,而我只想展示该车道组合的最佳运行时间。
$sqlstring1="SELECT * FROM laptimes WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}' ORDER BY laptime ASC";
我试图像这样使用SELECT,但是后来我只得到54行?我只记录了两个时间,所以没有显示其他人的时间。
$sqlstring1 = "SELECT t1.* FROM laptimes t1
JOIN (
SELECT player, MIN(laptime) AS min_laptime
FROM laptimes
GROUP BY player
) AS t2 ON t1.player = t2.player AND t1.laptime = t2.min_laptime
WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}'
ORDER BY laptime ASC";
我也尝试了不同的SELECTS,例如LEFT JOIN。 $ trackselect和$ carselect是php页面上下拉菜单中的值,它们似乎在两种情况下均有效。 $ choice值来自php页面上的两个不同按钮。按钮1设置$ choice =“”。按钮2设置$ choice =“ AND玩家喜欢'Maskmagog'”。这仅用于显示我的运动时间。它似乎正在工作。
问题:为什么在第二个SELECT中没有选择某些行?
以下是第一个SELECT的前5个输出:
1. sel Ginetta G40 Junior 00:56.017
2. {DFRUK}michaeldimel Ginetta G40 Junior 00:56.149
3. Yorkshire Farmer Ginetta G40 Junior 00:56.709
4. piquet Ginetta G40 Junior 00:56.756
5. Oomph Ginetta G40 Junior 00:56.981
和第二个SELECT:
1. Yorkshire Farmer Ginetta G40 Junior 00:56.709
2. saya777 Ginetta G40 Junior 00:57.002
3. Lamb4chop™ Ginetta G40 Junior 00:57.067
4. Jonge Ginetta G40 Junior 00:57.250
5. NsGTR35 Ginetta G40 Junior 00:57.296
如您所见,只有“约克郡农民”幸存下来并显示在两个选择中,我不明白为什么。
这是完整的php页面,位于Pastebin上:https://pastebin.com/ALTzfm2S
编辑:由于下面的评论,我终于明白了为什么第二个SELECT无效。它首先选择选手的最小圈速,而不管赛道/赛车如何。然后将其应用到WHERE中,并且将在其他赛车/赛道中设置了最低空转时间的玩家从结果中删除。天哪! :)
编辑2:看来我不能标记多个答案。两种解决方案似乎都能奏效,非常感谢所有参与人员!我无法确定一个答案是否更好/更有用/更正确。
答案 0 :(得分:1)
您的问题是您的子查询正在返回玩家无论赛道还是汽车的最小圈速。您需要用它返回玩家在其比赛的每条赛道上每辆车的最小圈速,因此您需要将GROUP BY
更改为
GROUP BY player, track, carname
,然后还需要将track
和carname
添加到子查询SELECT
和JOIN
中。因此您的查询应如下所示:
$sqlstring1 = "SELECT t1.* FROM laptimes t1
JOIN (
SELECT player, track, carname, MIN(laptime) AS min_laptime
FROM laptimes
GROUP BY player, track, carname
) AS t2 ON t1.player = t2.player AND t1.laptime = t2.min_laptime AND t1.track = t2.track AND t1.carname = t2.carname
WHERE track = '{$trackselect}' {$choice} AND carname LIKE '{$carselect}'
ORDER BY laptime ASC";
答案 1 :(得分:0)
根据您的要求,您不需要嵌套的SELECT
。您可以将条件添加到内部查询中并使用它:
SELECT player, MIN(laptime) AS min_laptime
FROM laptimes
WHERE track = ?
AND carname LIKE ?
AND player LIKE ?
GROUP BY player
ORDER BY laptime ASC
如果不需要所有条件,则可以动态构建sql语句字符串,仅添加所需的条件。然后,绑定所需数量的变量并执行该语句。