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

SQL MAX GROUP BY查询如何包含最大行对应的附加列

原有查询的问题点
  • GROUP BY 逻辑冗余:用来分组的月初日期计算(DATEADD(MONTH, DATEDIFF(MONTH,0, [tDate]),0))本身已经唯一锁定了某一年的自然月,完全可以确定对应的月份名和年份值,再把FORMAT生成的月份名、年份字段加入GROUP BY没有任何必要,只会增加计算开销,甚至可能因为FORMAT受服务器区域设置影响,出现同个自然月被拆成多个分组的错误。
  • 触发语法报错的根本原因:纯GROUP BY聚合场景下,SELECT列表中的非聚合列必须要么出现在GROUP BY维度中,要么被聚合函数包裹。需要带出的消费描述列既不属于分组维度,也无法被聚合,硬加必然触发报错,这是SQL语法的基本约束,不是代码写法的问题。
可实现带描述列的方案

方案1:窗口函数实现(主流版本优先选用)

先给每个自然月内的所有消费记录按金额倒序排名,只取每个月排名第1的行,即可带出全部需要的字段,代码如下:

WITH ranked_consume AS (
    SELECT 
        DATEADD(MONTH, DATEDIFF(MONTH,0, [tDate]),0) AS tDate,
        -- 指定zh-CN文化格式,稳定输出中文月份名
        FORMAT([tDate], 'MMMM', 'zh-CN') AS tMonth,
        FORMAT([tDate], 'yyyy') AS tYear,
        [tAmount],
        [tDesription],
        -- 按自然月分区,组内按消费金额从高到低排序
        ROW_NUMBER() OVER (
            PARTITION BY DATEADD(MONTH, DATEDIFF(MONTH,0, [tDate]),0) 
            ORDER BY [tAmount] DESC
        ) AS amount_rank
    FROM t
    WHERE [tDate] >= DATEADD(month, -6, getDate())
)
SELECT tDate, tMonth, tYear, tAmount, tDesription
FROM ranked_consume
WHERE amount_rank = 1
ORDER BY tDate DESC

注意:如果同一个月存在两笔及以上金额完全相同的最大消费,ROW_NUMBER()只会随机选取其中一行返回。如果需要把所有同金额最大值的记录全部带出,把ROW_NUMBER()替换为RANK()即可。

方案2:关联匹配实现(适配低版本SQL Server)

针对SQL Server 2008及更早不支持窗口函数的版本,可以先聚合算出每个月的最大金额,再回连原表匹配对应记录,代码如下:

WITH month_max_amount AS (
    SELECT 
        DATEADD(MONTH, DATEDIFF(MONTH,0, [tDate]),0) AS month_start,
        MAX([tAmount]) AS max_amount
    FROM t
    WHERE [tDate] >= DATEADD(month, -6, getDate())
    GROUP BY DATEADD(MONTH, DATEDIFF(MONTH,0, [tDate]),0)
)
SELECT 
    m.month_start AS tDate,
    FORMAT(t.[tDate], 'MMMM', 'zh-CN') AS tMonth,
    FORMAT(t.[tDate], 'yyyy') AS tYear,
    m.max_amount AS tAmount,
    t.[tDesription]
FROM month_max_amount m
INNER JOIN t 
    ON m.month_start = DATEADD(MONTH, DATEDIFF(MONTH,0, t.[tDate]),0)
    AND m.max_amount = t.[tAmount]
ORDER BY m.month_start DESC
原有代码的细节修正
  • 原代码中FORMAT生成月份名的逻辑没有指定语言文化参数,在非中文服务器环境下会输出英文月份名,无法匹配预期的「一月、二月」格式,需要补充'zh-CN'的第三个参数保证结果稳定。
  • 原代码的GROUP BY可以直接去掉对FORMAT(tDate, 'MMMM')和FORMAT(tDate, 'yyyy')的引用,只保留月初日期的计算逻辑即可,减少不必要的计算开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 18:06:04