双分组依据最大日期

Double group by with max date

我一直在环顾四周,想知道如何进行双重分组。我有这个 fees table:

name end_date last_check fee
bob 2019-01-01 2020-10-11 42
bob 2019-01-01 2020-11-25 41.45
bob 2020-01-01 2020-12-20 24.32
bob 2020-01-01 2021-02-03 29.30
sam 2019-01-01 2020-10-11 27.23
sam 2020-01-01 2020-12-20 23.23
sam 2020-01-01 2020-12-27 320.3
sam 2020-01-01 2021-02-03 320.3
bill 2021-01-01 2021-01-01 28.23

我想先分组 name。然后按 end_date 分组,但仅 select 基于 last_check 的最新行。所以我想要的输出是:

name end_date last_check fee
bob 2019-01-01 2020-11-25 41.45
bob 2020-01-01 2021-02-03 29.30
sam 2019-01-01 2020-10-11 27.23
sam 2020-01-01 2021-02-03 320.3
bill 2021-01-01 2021-01-01 28.23

我的table:

CREATE TABLE fees (
 name varchar2(32) not null,
 end_date date not null,
 last_check date not null,
 fee number(5, 2) not null
);

INSERT INTO fees (name, end_date, last_check, fee) VALUES ('bob', TO_DATE('2019-01-01','YYYY-MM-DD'), TO_DATE('2020-10-11','YYYY-MM-DD'), 42);
INSERT INTO fees (name, end_date, last_check, fee) VALUES ('bob', TO_DATE('2019-01-01','YYYY-MM-DD'), TO_DATE('2020-11-25','YYYY-MM-DD'), 41.45);
INSERT INTO fees (name, end_date, last_check, fee) VALUES ('bob', TO_DATE('2020-01-01','YYYY-MM-DD'), TO_DATE('2020-12-20','YYYY-MM-DD'), 24.32);
INSERT INTO fees (name, end_date, last_check, fee) VALUES ('bob', TO_DATE('2020-01-01','YYYY-MM-DD'), TO_DATE('2021-02-03','YYYY-MM-DD'), 29.3);
INSERT INTO fees (name, end_date, last_check, fee) VALUES ('sam', TO_DATE('2019-01-01','YYYY-MM-DD'), TO_DATE('2020-10-11','YYYY-MM-DD'), 27.23);
INSERT INTO fees (name, end_date, last_check, fee) VALUES ('sam', TO_DATE('2020-01-01','YYYY-MM-DD'), TO_DATE('2020-12-20','YYYY-MM-DD'), 23.23);
INSERT INTO fees (name, end_date, last_check, fee) VALUES ('sam', TO_DATE('2020-01-01','YYYY-MM-DD'), TO_DATE('2020-12-27','YYYY-MM-DD'), 320.3);
INSERT INTO fees (name, end_date, last_check, fee) VALUES ('sam', TO_DATE('2020-01-01','YYYY-MM-DD'), TO_DATE('2021-02-03','YYYY-MM-DD'), 320.3);
INSERT INTO fees (name, end_date, last_check, fee) VALUES ('bill', TO_DATE('2021-01-01','YYYY-MM-DD'), TO_DATE('2021-01-01','YYYY-MM-DD'), 28.23);

我的尝试:

SELECT name, end_date, max(last_check), fee
from fees
GROUP BY name, end_date, fee

一种方法是使用 row_number()!

如果您需要经常构建 SQL,请了解“分区依据”...它会改变您的工作!

select
   a.*
from
   (
      select
         f.*,
         row_number() over(partition by f.name, f.end_date order by f.last_check desc) as rn
      from
         fees f
   ) a where a.rn = 1;

又一个可以收藏在你的武器库中。它可能没有那么高效,但我发现它更能描述意图

select distinct 
       name, 
       end_date, 
       max(last_check) over (partition by name, end_date), 
       first_value(fee) over (partition by name, end_date order by last_check desc)
from fees;