SQL DISTINCT MIN() - 我做错了什么?

问题描述 投票:0回答:2

我最近开始学习 SQL,设置了服务器,尝试使用我找到的 kaggle DB 进行一些练习。

我希望看到每圈的记录器(意味着赛道名称字段应该是不同的),但它列出了所有圈记录。

我已经尝试过:

select distinct 
    r.name, min(t.fastestlaptime) as 'Fastest lap', d.surname,  d.driverId, r.year
from
    races r
inner join 
    results t on r.raceID = t.raceID
inner join 
    drivers d on t.driverID = d.driverID
where 
    (t.fastestlaptime not in ('\N'))
group by 
    r.name, d.forename, d.surname, d.driverId, r.year
order by 
    r.name

我得到这个结果:

名字 最快圈速 姓氏 驱动程序ID
70周年大奖赛 1:28.451 汉密尔顿 1 2020
70周年大奖赛 1:29.465 维斯塔潘 830 2020
70周年大奖赛 1:29.477 阿尔本 848 2020
阿布扎比大奖赛 1:26.103 维斯塔潘 830 2021
阿布扎比大奖赛 1:26.419 佩雷斯 815 2021
阿布扎比大奖赛 1:26.615 汉密尔顿 1 2021
澳大利亚大奖赛 1:28.321 维伦纽夫 35 2006年
澳大利亚大奖赛 1:28.336 佩雷斯 815 2017
澳大利亚大奖赛 1:28.416 格洛克 10 2009

ofc,我只是复制粘贴了一些结果,有 7.6k 行,而不是只显示具有唯一轨道名称的行。

有人可以向我解释一下吗?我不明白这个概念:D

我想列出不同的赛道名称、单圈记录、录音机名称、录音机 ID 和旁边的年份。

sql sql-server distinct sql-server-2019
2个回答
1
投票

您可能想要每条赛道的最快圈速?这通常不是通过聚合来解决,而是通过 ROW_NUMBER() 来解决,例如:

select *
from 
(
        select  *
        ,   row_number() over(partition by name order by try_cast([Fastest lap] as time)) as sort 
        from (
        VALUES  (N'70th Anniversary Grand Prix', N'1:28.451', N'Hamilton', 1, 2020)
        ,   (N'70th Anniversary Grand Prix', N'1:29.465', N'Verstappen', 830, 2020)
        ,   (N'70th Anniversary Grand Prix', N'1:29.477', N'Albon', 848, 2020)
        ,   (N'Abu Dhabi Grand Prix', N'1:26.103', N'Verstappen', 830, 2021)
        ,   (N'Abu Dhabi Grand Prix', N'1:26.419', N'Pérez', 815, 2021)
        ,   (N'Abu Dhabi Grand Prix', N'1:26.615', N'Hamilton', 1, 2021)
        ,   (N'Australian Grand Prix', N'1:28.321', N'Villeneuve', 35, 2006)
        ,   (N'Australian Grand Prix', N'1:28.336', N'Pérez', 815, 2017)
        ,   (N'Australian Grand Prix', N'1:28.416', N'Glock', 10, 2009)
        ) t (name,[Fastest lap],surname,driverId,year)
    ) x
where sort = 1

row_number() over(partition by name order by try_cast([Fastest lap] as time))
创建一个从 1 到 ... 的排序列,该列按赛道名称分组,然后按最快圈数对结果进行排序。我使用 try_cast 来避免奇怪的时间,你也不应该使用字符串。

然后您必须将选择包装在子查询中,因为 ROW_NUMBER() 窗口函数不能直接出现在 WHERE 子句中,因此:

where sort = 1


0
投票

在 SQL 中,distinct 是多余的。您按“d.forename、d.surname、d.driverId、r.year”和“r.name”进行分组,因此您将得到 min() per:

r.Name,然后每个名字,d.forename,d.surname,d.driverId,r.year。这意味着,例如,兰多·诺里斯(Lando Norris)在任何一年中都没有在任何赛道上最快,但在发车区上,那么您还会看到诺里斯在他在发车区的所有年份中所有赛道上的所有最快圈速:好吧。

如果您想要列出谁在每条赛道上获得最快单圈以及每年的计时,那么您需要的是获取每年每条赛道的 min() ,然后获取车手的其他信息。即:(基于您当前的 SQL,没有看到您拥有的实际数据):

select fL.name, fL.FastestLap as [Fastest lap], 
   d.surname,  d.driverId, fL.year
from 
(select r.Name, r.raceId, r.Year, min(t.fastestlaptime) as FastestLap,
from races r
inner join results t
on r.raceID=t.raceID
group by r.Name, r.raceId, r.Year) fL
inner join results t on t.RaceID = fL.RaceId 
    and t.fastestLapTime = fL.FastestLap
inner join drivers d on t.driverID = d.driverID
order by r.name;
© www.soinside.com 2019 - 2024. All rights reserved.