【问题标题】:TSQL to max multiple columns in sequenceTSQL按顺序最大化多列
【发布时间】:2021-10-21 09:46:07
【问题描述】:

我的示例源代码如下

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 查询,该查询将返回一个按站点和服务分组的表,它首先确定什么是 max yr,然后通过先前确定的 max yr 返回 mo 的最大值

我想要的输出如下

| 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 聚合来获取这两个值。所以你需要一个日期(如果我们做出假设,日期部分无关紧要 - 你看到你的吗?)。现在如何从 部分生成日期?
  • 这能回答你的问题吗? Get top 1 row of each group

标签: sql-server tsql window-functions


【解决方案1】:

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

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

【讨论】:

  • 子树成本较低。
【解决方案2】:

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

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

【讨论】:

  • 在 Yr、Month 和 FIRST_VALUE() 之后又测试了两个级别,并通过每个前面的最大级别进行了出色的钻取。谢谢!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-06
  • 2021-12-26
  • 2013-10-22
  • 1970-01-01
相关资源
最近更新 更多