TSQL按顺序最大化多列

TSQL to max multiple columns in sequence

我的示例源代码如下

declare @t1 as table
(
    site varchar(max),
    service varchar(max),
    yr integer, 
    mo integer
)

insert into @t1
    select *
    from 
        (values
            ('site1', 'service1', 2021, 1),
            ('site1', 'service1', 2021, 10),
            ('site1', 'service1', 2020, 12),
            ('site1', 'service1', 2019, 9),
            ('site1', 'service2', 2014, 5),
            ('site1', 'service2', 2015, 6),
            ('site1', 'service2', 2016, 7),
            ('site1', 'service2', 2016, 9),
            ('site2', 'service3', 2010, 2),
            ('site2', 'service3', 2011, 1),
            ('site2', 'service3', 2012, 3),
            ('site2', 'service3', 2012, 8) ) t (a, b, c, d)

我想编写一个 SQL 查询,它将 return 按站点和服务分组的 table 首先确定什么是最大年份,然后 return mo的最大值由之前确定的max yr

我想要的输出如下

| site  | service  | maxYr | maxMo |
|-------|----------|-------|-------|
| site1 | service1 | 2021  | 10    |
| site1 | service2 | 2016  | 9     |
| site2 | service3 | 2012  | 8     |

我目前可以通过关注

实现
select 
    a.site, a.service, a.yr as maxYr, max(a.mo) as maxMo
from 
    @t1 a
where 
    exists (select *
            from
                (select b.site, b.service, max(b.yr) as maxYr
                 from @t1 b
                 group by b.site, b.service) c
            where a.site = c.site
              and a.service = c.service
              and a.yr = c.maxYr)
group by 
    a.site, a.service, a.yr

我想知道是否有更好的方法通过单个查询来实现这一点,例如

select 
    site, service, max(yr) as maxYr, 
    max(mo) over (partition by site, service order by max(yr)) as maxMo 
from 
    @t1 
group by 
    site, service

如果我需要像 Yr-Month-Date 那样做进一步的聚合,我可能更容易通过单个查询来实现。

您可以使用 MAX()FIRST_VALUE() window 函数:

select distinct site, service,
       max(yr) over (partition by site, service) as maxYr,
       first_value(mo) over (partition by site, service order by yr desc, mo desc) as maxMo
from @t1;

参见demo

如果您有答案,您也可以使用

ROW_NUMBER 按 SITE 和 SERVICE 降序排列的功能和顺序:

SELECT SITE,SERVICE,YR,MO 
FROM
(
    SELECT *, ROW_NUMBER() OVER(PARTITION BY SITE, SERVICE ORDER BY YR DESC, MO DESC ) RN
    FROM @t1
) X
WHERE X.RN = 1