从包含联接的MIN查询中选择ID

时间:2019-08-22 01:13:19

标签: mysql

对不起标题,标题很不好!

我有以下相关表格:

Times
+--------+----------+-------------+------+---------+
| TimeID | PlayerID | MapCourseID | Mode | RunTime |
+--------+----------+-------------+------+---------+
Checkpoints
+--------------+--------+------------+---------+
| CheckpointID | TimeID | Checkpoint | RunTime |
+--------------+--------+------------+---------+
Maps
+-------+------+
| MapID | Name |
+-------+------+
MapCourses
+-----------+-------+--------+
| MapCourse | MapID | Course |
+-----------+-------+--------+

RunTime将其“时间”存储为int

我有一个查询,可以为所有课程和所有模式的特定地图MapID选择最快的时间

SELECT MIN(Times.RunTime), MapCourses.Course, Times.Mode 
FROM Times 
INNER JOIN MapCourses ON MapCourses.MapCourseID=Times.MapCourseID 
INNER JOIN Players ON Players.PlayerID=Times.PlayerID
WHERE Players.Cheater=0 AND MapCourses.MapID=%d 
GROUP BY MapCourses.Course, Times.Mode;

哪个可以正常工作,但是现在我要进行另一个查询,以选择最快时间的检查点,因为检查点与TimeID相关联

我试图做这样的事情

SELECT * FROM Checkpoints 
  INNER JOIN (
    SELECT 
        MIN(Times.RunTime), 
        MapCourses.Course, 
        Times.Mode, 
        MapCourses.MapID, 
        Players.SteamID32 
    FROM 
      Times 
      INNER JOIN MapCourses ON MapCourses.MapCourseID = Times.MapCourseID 
      INNER JOIN Players ON Players.PlayerID = Times.PlayerID
    WHERE 
      Players.Cheater = 0 
      AND MapCourses.MapID = %d 
    GROUP BY 
      MapCourses.Course, 
      Times.Mode
   ) AS wrs ON Checkpoints.TimeID = wrs.TimeID

也尝试过这样的事情:

SELECT 
  Checkpoints.RunTime, 
  Checkpoints.Checkpoint, 
  MapCourses.Course, 
  Times.Mode, 
  Times.TimeID, 
  Players.Alias 
FROM 
  Checkpoints 
  INNER JOIN Times ON Times.TimeID = Checkpoints.TimeID 
  INNER JOIN MapCourses ON MapCourses.MapCourseID = Times.MapCourseID 
  INNER JOIN Players ON Players.PlayerID = Times.PlayerID
WHERE 
  Players.Cheater = 0 
  AND MapCourses.MapID = %d 
  AND Times.RunTime = (
    SELECT 
      MIN(Times.RunTime) 
    FROM 
      Times 
    WHERE 
      Times.MapCourseID = MapCourses.MapCourseID 
      AND Mode = Times.Mode
  )

似乎都没有真正起作用,任何帮助都很好,谢谢!

基本上,如果我正在使用地图ID 50,那么我已经拥有一个查询,该查询可在所有模式和课程中获得地图ID 50上最快的时间,我要构建的查询是一个获取检查点的查询地图ID 50上每个课程和模式最快的时间

2 个答案:

答案 0 :(得分:0)

如果我正确地遵循了此规定,您是否希望每个Checkpoint的Checkpoints.TimeID最短,格式与上述类似?

ShrinkFlag

显然无法访问您的数据库,但我无法对此进行测试,但这似乎是您要的?

[编辑]

啊,所以您想保留最短时间,但想在返回值中添加检查点:

SELECT MIN(Checkpoints.TimeID), MapCourses.Course, Checkpoints.Checkpoint, Times.Mode 
FROM Checkpoints
INNER JOIN Times ON Checkpoints.TimeID=Times.TimeID
INNER JOIN MapCourses ON MapCourses.MapCourseID=Times.MapCourseID 
INNER JOIN Players ON Players.PlayerID=Times.PlayerID
WHERE Players.Cheater=0 AND MapCourses.MapID=%d 
GROUP BY MapCourses.Course, Checkpoints.Checkpoint, Times.Mode;

因此,这应该返回最快的时间,地图,检查点,然后返回模式。

答案 1 :(得分:0)

我们可以做这样的事情:

SELECT c.checkpointid
     , c.timeid
     , c.checkpoint
     , c.runtime
     , ...
  FROM ( SELECT t.mapcourseid
              , t.mode
              , MIN(r.runtime) AS min_runtime
           FROM Times r
           JOIN Players p
             ON p.playerid    = r.playerid
            AND p.cheater     = 0
           JOIN MapCourses s
             ON s.mapcourseid = t.mapcourse_id
            AND s.mapid       = ?
          GROUP
             BY t.mapcourseid
              , t.mode
       ) q
  JOIN Times t
    ON t.runtime     = q.min_runtime
   AND t.mapcourseid = q.mapcourseid
  JOIN Checkpoints c
    ON c.timeid      = t.timeid

这里的窍门是使用查询作为内联视图。从paren内部的查询返回的结果作为结果集返回,然后由外部查询像表一样使用。 MySQL将其称为“派生表”。

在外部SELECT列表中,我们可以包括对qt以及c中的列的引用。

注意:如果t中有两行或更多行与最小运行时相匹配(由q返回),则查询将返回所有匹配的行。

规范尚不清楚。该答案中的查询满足一种特定的解释。