【问题标题】:Get top 1 row of each Id by Where in通过 Where in 获取每个 Id 的前 1 行
【发布时间】:2020-01-13 02:54:13
【问题描述】:

我有一个表,我想在其中获取每个参数的最新条目

select GpsData.VehicleId, GpsData.Id, GpsData.DateTime
from GpsData
where GpsData.VehicleId in (44, 1054, 1055, 31, 22, 1058)
order by GpsData.VehicleId desc;

【问题讨论】:

    标签: sql-server tsql query-performance where-in


    【解决方案1】:

    NOT EXISTS:

    select g.VehicleId, g.Id, g.DateTime
    from GpsData g
    where g.VehicleId in (44, 1054, 1055, 31, 22, 1058)
    and not exists (
      select 1 from GpsData
      where VehicleId = g.VehicleId and DateTime > g.DateTime 
    )
    order by g.VehicleId desc;
    

    或者用row_number()窗口函数:

    select t.VehicleId, t.Id, t.DateTime
    from (
      select VehicleId, Id, DateTime,
        row_number() over (partition by VehicleId order by DateTime desc) as rn   
      from GpsData 
      where VehicleId in (44, 1054, 1055, 31, 22, 1058)
    ) as t
    where t.rn = 1
    order by t.VehicleId desc;
    

    【讨论】:

    • 我更喜欢第二种方法...我会将FROM(...) 转换为CTE,但这只是语法糖。从我这边 +1。
    【解决方案2】:

    您可以使用TOP 1 WITH TIES

    SELECT TOP 1 WITH TIES
        VehicleId, 
        Id, 
        [DateTime]
    FROM GpsData
    WHERE VehicleId in (44, 1054, 1055, 31, 22, 1058)
    ORDER BY ROW_NUMBER() OVER (PARTITION BY VehicleId ORDER BY [DateTime] DESC)
    

    我们可以使用动态查询如下:

     DECLARE @Ids NVARCHAR(MAX) = '44, 1054, 1055, 31, 22, 1058', @sql NVARCHAR(3000)
    
     SET @sql = '
        SELECT TOP 1 WITH TIES VehicleId, 
            Id, 
            [DateTime] 
        FROM GpsData 
        WHERE VehicleId IN (' + @ids + ') 
        ORDER BY ROW_NUMBER() OVER (PARTITION BY VehicleId ORDER BY [DateTime] DESC)'
    
    EXEC(@sql) 
    

    【讨论】:

    • Susang,我真的很喜欢这种巧妙的方法,但我不得不发现,它非常慢...排序将执行两次(一次用于ROW_NUMBER,一次用于ORDER BY . 较大的集合相当不利...最好使用CTE和ROW_NUMBER作为列并在最后使用WHERE RNr=1...
    • 非常感谢。我如何为这种方法使用参数声明@Ids nvarchar(Max) =44, 1054, 1055, 31, 22, 1058 SELECT TOP 1 WITH TIES VehicleId, Id, [DateTime] FROM GpsData WHERE VehicleId in (@ids) ORDER BY ROW_NUMBER() OVER(PARTITION BY VehicleId ORDER BY [DateTime] DESC)
    • 我们可以使用上面更新的动态查询,请检查。
    猜你喜欢
    • 1970-01-01
    • 2021-01-07
    • 2021-12-29
    相关资源
    最近更新 更多