You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TSQL按site、service分组先取最大yr再取对应最大mo的更优实现方法

解决方案

下面提供两种简洁高效的实现方式,均支持后续年-月-日层级的扩展需求:


方案1:数值拼接法(最适合层级扩展,代码极简)

核心逻辑是将年、月按权重拼接为整数,最大值天然对应「最大年+该年最大月」,后续扩展层级仅需调整权重即可,无需修改整体结构。

SELECT
    site,
    service,
    MAX(yr * 100 + mo) / 100 AS maxYr,
    MAX(yr * 100 + mo) % 100 AS maxMo
FROM @t1
GROUP BY site, service

如果后续要扩展到年-月-日层级,仅需调整计算规则:

SELECT
    site,
    service,
    MAX(yr * 10000 + mo * 100 + [day]) / 10000 AS maxYr,
    (MAX(yr * 10000 + mo * 100 + [day]) % 10000) / 100 AS maxMo,
    MAX(yr * 10000 + mo * 100 + [day]) % 100 AS maxDay
FROM @t1
GROUP BY site, service

优势:仅需一次表扫描,无嵌套子查询,性能最优,层级扩展成本极低。


方案2:排序取Top1法(逻辑直观,无需数值运算)

如果不想做数值计算,可以用开窗函数排序后取每组第一条,逻辑非常好理解,扩展也很方便:

SELECT site, service, yr AS maxYr, mo AS maxMo
FROM (
    SELECT 
        site, service, yr, mo,
        ROW_NUMBER() OVER (PARTITION BY site, service ORDER BY yr DESC, mo DESC) AS rn
    FROM @t1
) t
WHERE rn = 1

扩展到年-月-日层级只需要在ORDER BY后面加[day] DESC即可。


原有写法问题说明

你尝试写的窗口函数写法逻辑存在缺陷:分组后每个site+service分组仅返回一行,此时max(mo) over (...)取的是该分组所有月份的最大值,而非最大年对应的月份最大值,比如分组内存在「2021年1月、2020年12月」时,会错误返回maxMo为12,而非正确的1。
你原来的EXISTS写法虽然逻辑正确,但需要多次扫描表,性能不如上述两种方案,且层级扩展时需要修改多层子查询,维护成本高。


内容的提问来源于stack exchange,提问作者smpa01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 13:09:01