使用 MAX 查找给定其他属性的最新时间

Using MAX to find the lastest time given other attribtues

这是数据集布局的示例: https://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=b537554bb5e9dbde4f6c662fc302db5f

我想编写一个 select 查询以按日期获取每个供应商到达的最后一个产品。

示例数据:

Line | date                    | Vendor             | Product_Name | Arrival_Time
---: | :---------------------- | :----------------- | :----------- | :-----------
   1 | 2020-09-01 00:00:00.000 | Fruits Fruit Fuits | Bananas      | 14:30:00    
   2 | 2020-09-01 00:00:00.000 | Fruits Fruit Fuits | Apples       | 13:30:00    
   3 | 2020-09-01 00:00:00.000 | Fruits Fruit Fuits | Oranges      | 08:30:00    
   4 | 2020-09-02 00:00:00.000 | Fruits Fruit Fuits | Apples       | 15:30:00    
   5 | 2020-09-02 00:00:00.000 | Fruits Fruit Fuits | Oranges      | 12:30:00    
   6 | 2020-09-02 00:00:00.000 | Fruits Fruit Fuits | Bananas      | 04:30:00    
   7 | 2020-09-01 00:00:00.000 | Fruits & More      | Bananas      | 21:30:00    
   8 | 2020-09-01 00:00:00.000 | Fruits & More      | Apples       | 00:30:00    
   9 | 2020-09-01 00:00:00.000 | Fruits & More      | Oranges      | 05:30:00    
  10 | 2020-09-02 00:00:00.000 | Fruits & More      | Apples       | 23:30:00    
  11 | 2020-09-02 00:00:00.000 | Fruits & More      | Oranges      | 15:30:00    
  12 | 2020-09-02 00:00:00.000 | Fruits & More      | Bananas      | 01:30:00    

期望的结果:

Line | date                    | Vendor             | Product_Name | Arrival_Time
---: | :---------------------- | :----------------- | :----------- | :-----------
   1 | 2020-09-01 00:00:00.000 | Fruits Fruit Fuits | Bananas      | 14:30:00    
   4 | 2020-09-02 00:00:00.000 | Fruits Fruit Fuits | Apples       | 15:30:00    
   7 | 2020-09-01 00:00:00.000 | Fruits & More      | Bananas      | 21:30:00    
  10 | 2020-09-02 00:00:00.000 | Fruits & More      | Apples       | 23:30:00   

因此,在提供的示例中,我希望查询到 return 第 1 行(对于 Fruits Fruits Fruits,14:30 是 9 月 1 日的最晚时间),第 7 行(21:30 是Fruits & More 9/1最晚时间4号线(15:30是Fruits Fruits Fruits 9/1最晚时间)等

我想我缺少一个子查询,或者我可能需要 fiddle 我的分组依据。

一种方法使用相关子查询:

select a.*
from availability a
where a.arrival_time = (
    select max(a1.arrival_time)
    from availability a1
    where a1.vendor = a.vendor 
        and a1.date >= convert(date, a.date) 
        and a1.date < dateadd(day, 1, convert(date, a.date))
);

日期条件可以更简单地表示为 convert(date, a.date) = convert(date, a1.date),但上述表达式可能更有效,尤其是 (vendor, date, arrival_time).

上的索引

另一个典型的方法是window函数:

select *
from (
    select a.*, 
        row_number() over(partition by a.vendor, convert(date, a.date) order by a.arrival_time desc) rn
    from availability a
) a
where rn = 1

这应该适合你

select * from 
(
    select Line
         , date
         , vendor
         , product_name
         , arrival_time
         , row_number() over (partition by vendor, date order by arrival_time desc) num  
    from availability 
) data
where num = 1
order by Line

另一种选择是使用 WITH TIES 子句

例子

SELECT top 1 with ties * 
FROM  availability
order by row_number() over (partition by date,vendor order by arrival_time desc)

Returns

Line    date                    Vendor              Product_Name    Arrival_Time
7       2020-09-01 00:00:00.000 Fruits & More       Bananas         21:30:00
1       2020-09-01 00:00:00.000 Fruits Fruit Fuits  Bananas         14:30:00
10      2020-09-02 00:00:00.000 Fruits & More       Apples          23:30:00
4       2020-09-02 00:00:00.000 Fruits Fruit Fuits  Apples          15:30:00