SQL查询总交易额最高Top1客户交易记录并追加末尾汇总行
解决方案
基础信息梳理
- 操作表:
transactions,表字段为transaction_id、customer_id、transaction_amount、transaction_location - 需求规则:
- 动态筛选总交易金额最高的Top1客户
- 结果仅展示该客户所有交易的
transaction_id、Transaction_Amount字段 - 结果最后一行追加该客户的总交易金额,该行标识为
Total_Transactions_Amount
- 不需要使用自连接,通过窗口函数+分组汇总即可实现,查询效率比自连接方案更高。
完整SQL实现
支持所有兼容CTE、窗口函数的主流数据库(MySQL 8.0+、PostgreSQL、SQL Server等):
WITH customer_agg AS ( SELECT transaction_id, transaction_amount, -- 按客户维度计算总交易额并生成排名,并列第一的客户会全部保留 RANK() OVER (ORDER BY SUM(transaction_amount) OVER (PARTITION BY customer_id) DESC) AS cust_rk FROM transactions ) SELECT -- 汇总行第一列展示要求的标识,明细行展示交易ID CASE WHEN GROUPING(transaction_id) = 1 THEN 'Total_Transactions_Amount' ELSE transaction_id END AS transaction_id, -- 明细行展示单笔交易金额,汇总行展示总金额 SUM(transaction_amount) AS Transaction_Amount FROM customer_agg WHERE cust_rk = 1 -- 通过ROLLUP自动生成末尾汇总行 GROUP BY transaction_id, transaction_amount WITH ROLLUP -- 过滤ROLLUP生成的中间无效分组行,仅保留明细行和最终总汇总行 HAVING GROUPING(transaction_id) = 0 OR (GROUPING(transaction_id) = 1 AND GROUPING(transaction_amount) = 1);
实现说明
- 排名函数选择
RANK()而非ROW_NUMBER():如果存在多个客户总交易金额并列第一的场景,RANK()会返回所有符合Top1条件的客户数据,不会随机遗漏;如果业务要求仅返回任意一个Top1客户,将RANK()替换为ROW_NUMBER()即可。 - 无硬编码逻辑:不需要提前预知Top1客户的
customer_id,代码会自动计算排名筛选目标客户,适配数据动态变化的场景。 ROLLUP搭配GROUPING()函数:自动生成分组汇总行,同时可以精准识别汇总行位置,完成要求的标识配置,不需要额外拼接结果集。
内容的提问来源于stack exchange,提问作者flojo777
相关产品推荐
相关产品推荐

