SQL分组需求:按最近End_Date分组并取字母序最高Invoice_Name,同时汇总账户金额
解决账户分组汇总并关联最新日期及最高字母序发票的问题
首先,咱们先分析你现有SQL的问题:当同一账户的最新End_Date下存在多个Invoice_Name时,你的查询会返回多条记录——这是因为你在关联到最新日期的记录后,没有进一步筛选出该日期下字母序最高的发票,导致每个符合最新日期的发票都会生成一条汇总记录,而金额其实是重复的(因为SUM是按账户汇总的)。另外,你的SQL里提到的Table2看起来可能是笔误?从你提供的源数据来看,所有字段都在同一个表中,没必要关联另一个表来汇总金额。
下面是修正后的方案,用窗口函数+CTE的方式,既能清晰实现需求,又能避免重复记录:
完整SQL代码
WITH AccountTotal AS ( -- 第一步:汇总每个账户的总金额 SELECT AccountID, SUM(Amount) AS Total_Amount FROM YourTableName -- 替换成你的实际表名 GROUP BY AccountID ), LatestInvoiceDetails AS ( -- 第二步:筛选每个账户最新End_Date下字母序最高的发票记录 SELECT AccountID, Start_Date, End_Date, Invoice_Name, -- 按账户分组,先按End_Date倒序(取最新),再按Invoice_Name倒序(取字母序最高) ROW_NUMBER() OVER ( PARTITION BY AccountID ORDER BY End_Date DESC, Invoice_Name DESC ) AS RowRank FROM YourTableName ) -- 第三步:关联总金额和筛选后的发票详情 SELECT at.AccountID, at.Total_Amount AS Amount, lid.Start_Date, lid.End_Date, lid.Invoice_Name FROM AccountTotal at JOIN LatestInvoiceDetails lid ON at.AccountID = lid.AccountID WHERE lid.RowRank = 1 -- 只保留每个账户排名第一的记录 ORDER BY at.Total_Amount DESC;
代码说明
- AccountTotal CTE:单独汇总每个账户的总金额,确保金额计算准确,不会因为关联多条发票记录而重复计算。
- LatestInvoiceDetails CTE:使用
ROW_NUMBER()窗口函数,为每个账户的记录排序——先按End_Date降序(优先取最新的日期),再按Invoice_Name降序(同一日期下取字母序最高的发票),然后筛选出排名为1的记录,就是我们需要的目标发票信息。 - 最后将两个CTE通过
AccountID关联,得到每个账户唯一的汇总记录,完全符合你的需求。
用你提供的测试数据运行这段SQL,会得到你期望的结果:
| AccountID | Amount | Start_Date | End_Date | Invoice_Name |
|---|---|---|---|---|
| 1 | 400 | 03-05-2018 | 02-15-2022 | I77845 |
| 2 | 1000 | 03-01-2003 | 08-10-2012 | I84897 |
内容的提问来源于stack exchange,提问作者Aaron Connor
相关产品推荐
相关产品推荐

