【问题标题】:Max/min/count etc. not giving good value最大/最小/计数等没有给出好的价值
【发布时间】:2016-05-26 07:39:19
【问题描述】:

我有一个来自 ergast.com 的 f1 database。我试图在每场比赛中为每个车手获得最好的laptimepitstops 的数量,所以我编写了这样的 sql 查询:

SELECT results.driverId, results.constructorId, races.circuitId, races."year"-1949,
       results.statusId, results.positionOrder, results.grid, results.points, 
       results.laps, ISNULL(max(pitstops.stop), 0), min(laptimes.milliseconds), 
       results.fastestLapTime, drivers.forename, drivers.surname, circuits.name
FROM results 
INNER JOIN races 
   ON (results.raceId = races.raceId)
LEFT OUTER JOIN pitstops 
   ON (races.raceId = pitstops.raceId)
LEFT OUTER JOIN laptimes 
   ON (laptimes.raceId = races.raceId)
INNER JOIN drivers 
   ON (drivers.driverId = results.driverId)
INNER JOIN circuits 
   ON (circuits.circuitId = races.circuitId)
WHERE ((races."year"=2011) OR (races."year"=2012))
  AND ((races.circuitId = 1) OR (races.circuitId = 2))
GROUP BY results.driverId, constructorId, races.circuitId, races."year"-1949,
         statusId, positionOrder, grid, points, laps, fastestLapTime, forename,
         surname, circuits.name

不幸的是,对于给定比赛的每位车手,这给了我相同的最佳 laptimepitstops 数量。我该如何解决?我应该在group by 中添加一些内容吗?

【问题讨论】:

  • 因为你是按fastestLapTime分组的,不是吗?
  • 您可以更改您的 or 语句,对吗? (2011、2012)中的年份和(1、2)中的电路ID?
  • 能否请您为所有列添加一个限定符。例如:fastestLapTime 是否来自表 laptimes?然后laptimes.fastestLapTime。等
  • @ThorstenKettner 完成
  • @IvanStarostin 我已经添加它来检查结果,不幸的是删除它并不会改变结果

标签: sql sql-server tsql


【解决方案1】:

您仅在raceId 上加入进站,从而获得每场比赛的最大进站。但是您会说“以及给定比赛中每位车手的进站次数”。这表明进站应该与车手相关,例如:

LEFT OUTER JOIN pitstops 
   ON (results.raceId = pitstops.raceId and results.driverId = pitstops.driverId)

单圈时间也是如此。

(您的查询中可能有更多错误。如果您需要更多帮助,请使用表名限定所有列,以便我们查看哪些列在哪个表中。最好是表定义。)

【讨论】:

  • 谢谢,是这个问题,我不知道你可以同时通过两组列连接表格
  • 是的,这是必不可少的。您必须连接所有相关列上的表。否则你会得到你不想要的重复和组合。例如,您的加入将每个进站与碰巧参加同一比赛的每个车手结合在一起。
【解决方案2】:

这是另一个“答案”:-)

您正在使用技术 ID(raceId、driverId 等),但您很惊讶必须加入多个列。对于基于技术 ID 的数据库,这确实有点不典型。那么让我们来看看为什么会这样......

应该有一个表格列出每场比赛的车手。我们就叫它participation

participation(participationid, raceid, driverid)

有了这样一个表,您的其他表将不再包含raceiddriverid 的组合,而只包含participationid

pitstops(pitstopid, participationid, stop, ...)

laptimes(laptimeid, participationid, milliseconds, ...)

results(resultid, participationid, points, ...)

您只需要相应地加入该列:

LEFT OUTER JOIN pitstops 
  ON pitstops.participationid = results.participationid

不过,我认为每个raceiddriverid 只能有一个结果记录?那么您的参与表实际上就是结果表(只是名称更差:-)。因此,您应该在表和引用它的其他表中有一个 resultid:

pitstops(pitstopid, resultid, stop, ...)

laptimes(laptimeid, resultid, milliseconds, ...)

您只需要相应地加入该列:

LEFT OUTER JOIN pitstops 
  ON pitstops.resultid = results.resultid

【讨论】:

    【解决方案3】:

    添加到已经给出的答案:您可以通过获取子查询中的聚合来简化查询(在FROM 子句或SELECT 子句中)。例如:

    select 
      results.driverid,
      results.constructorid,
      races.circuitid,
      races."year" - 1949,
      results.statusid,
      results.positionorder,
      results.grid,
      results.points,
      results.laps,
      (
        select coalesce(max(stop), 0)
        from pitstops
        where pitstops.raceid = results.raceid
        and pitstops.driverid = results.driverid
      ) as max_pitstops,
      (
        select coalesce(min(milliseconds), 0)
        from laptimes
        where laptimes.raceid = results.raceid
        and laptimes.driverid = results.driverid
      ) as min_laptimes,
      results.fastestlaptime,
      drivers.forename,
      drivers.surname,
      circuits.name
    from results
    join drivers on drivers.driverid = results.driverid
    join races on races.raceid = results.raceid
    join circuits on circuits.circuitid = races.circuitid
    where races."year" in (2011, 2012)
    and races.circuitid in (1, 2);
    

    select 
      results.driverid,
      results.constructorid,
      races.circuitid,
      races."year" - 1949,
      results.statusid,
      results.positionorder,
      results.grid,
      results.points,
      results.laps,
      coalesce(pits.max_stop, 0) as max_pitstops,
      coalesce(laps.min_milliseconds, 0) as min_laptimes,
      results.fastestlaptime,
      drivers.forename,
      drivers.surname,
      circuits.name
    from results
    join drivers on drivers.driverid = results.driverid
    join races on races.raceid = results.raceid
    join circuits on circuits.circuitid = races.circuitid
    left join
    (
      select raceid, driverid, max(stop) as max_stop
      from pitstops
      group by raceid, driverid
    ) pits on pits.raceid = results.raceid and pits.driverid = results.driverid
    left join
    (
      select raceid, driverid, min(milliseconds) as min_milliseconds
      from laptimes
      group by raceid, driverid
    ) laps on laps.raceid = results.raceid and laps.driverid = results.driverid
    where races."year" in (2011, 2012)
    and races.circuitid in (1, 2);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      • 2015-10-29
      • 2020-08-30
      相关资源
      最近更新 更多