SQL查询:分组统计供应商月度支付额及总支付额(TOP10需求)
解决TOP10供应商月度支付+总支付额的SQL查询问题
我来帮你搞定这个查询!你的需求是找出支付总额最高的TOP10供应商,同时展示每个供应商的月度支付明细和他们的总支付额,核心问题就是怎么把总支付额和月度明细结合起来,对吧?
核心思路
我们需要分两步拆解逻辑:
- 先计算每个供应商的总支付额,筛选出总额最高的前10个供应商;
- 针对这10个供应商,按月份分组计算月度支付额,同时把之前算出的总支付额关联到每一条月度记录中。
针对SQL Server的解决方案
下面是用CTE(公共表表达式)写的完整SQL,逻辑拆分得很清楚:
-- 第一步:计算所有供应商的总支付额 WITH VendorTotals AS ( SELECT Vendor, SUM(Amt) AS TotalAmt FROM VendorTable GROUP BY Vendor ), -- 第二步:筛选出总支付额最高的TOP10供应商 TopVendors AS ( SELECT TOP 10 Vendor, TotalAmt FROM VendorTotals ORDER BY TotalAmt DESC ) -- 第三步:关联原表,计算TOP10供应商的月度支付明细,并带上总支付额 SELECT tv.Vendor, -- 把日期格式化为"Jan-15"这种更易读的形式 FORMAT(vt.PayDate, 'MMM-yy') AS [Month], SUM(vt.Amt) AS MonthlyAmt, tv.TotalAmt FROM VendorTable vt JOIN TopVendors tv ON vt.Vendor = tv.Vendor -- 按供应商、月份分组,总支付额是每个供应商的固定值,所以可以直接加入GROUP BY GROUP BY tv.Vendor, FORMAT(vt.PayDate, 'MMM-yy'), tv.TotalAmt -- 先按总支付额降序排序,让高支付供应商排在前面,再按月份排序方便查看同供应商的月度变化 ORDER BY tv.TotalAmt DESC, [Month]
针对MySQL的适配方案
如果用的是MySQL,语法有小细节调整(比如TOP 10换成LIMIT 10,日期格式化函数不同):
WITH VendorTotals AS ( SELECT Vendor, SUM(Amt) AS TotalAmt FROM VendorTable GROUP BY Vendor ), TopVendors AS ( SELECT Vendor, TotalAmt FROM VendorTotals ORDER BY TotalAmt DESC LIMIT 10 ) SELECT tv.Vendor, DATE_FORMAT(vt.PayDate, '%b-%y') AS `Month`, SUM(vt.Amt) AS MonthlyAmt, tv.TotalAmt FROM VendorTable vt JOIN TopVendors tv ON vt.Vendor = tv.Vendor GROUP BY tv.Vendor, DATE_FORMAT(vt.PayDate, '%b-%y'), tv.TotalAmt ORDER BY tv.TotalAmt DESC, `Month`
对你原有查询的补充说明
你原来的查询里,SUM(Amt)只能得到当前月份的支付额——因为你是按Vendor + 月份分组的。而总支付额是整个供应商的累计值,所以必须先单独计算总金额,再通过关联把它带到每一行月度记录里,这样才能同时展示月度数据和总额数据。
另外,排序时先按TotalAmt DESC,能让支付最高的供应商排在最前面,再按月份排序,方便查看同一个供应商的月度支付变化。
内容的提问来源于stack exchange,提问作者asmgx
相关产品推荐
相关产品推荐

