如何用SQL按商家统计交易数与总额并取每组Top3?
按商家统计交易数据并取每组前3条的SQL解决方法
第一种情况:每个商家的交易记录里取前3条,同时显示该商家的总交易数和总额
如果是要在每个商家的交易记录里挑前3条(比如按交易金额从高到低),同时展示这个商家的总交易次数和总金额,用PARTITION BY完全没问题,这正是窗口函数的典型用法。
假设你的交易表叫transactions,有merchant_id(商家ID)、transaction_id(交易ID)、amount(交易金额)这些字段,直接看示例代码:
WITH merchant_total AS ( -- 先算出每个商家的总交易数和总额 SELECT merchant_id, COUNT(transaction_id) AS total_trans_count, SUM(amount) AS total_amount FROM transactions GROUP BY merchant_id ), ranked_trans AS ( -- 给每个商家下的交易按金额降序排号,同商家内从1开始计数 SELECT t.merchant_id, t.transaction_id, t.amount, mt.total_trans_count, mt.total_amount, ROW_NUMBER() OVER (PARTITION BY t.merchant_id ORDER BY t.amount DESC) AS row_num FROM transactions t JOIN merchant_total mt ON t.merchant_id = mt.merchant_id ) -- 只留每组的前3条 SELECT * FROM ranked_trans WHERE row_num <= 3;
第二种情况:统计所有商家的交易数和总额后,取排名前3的商家
如果你的需求是从所有商家的统计结果里挑交易数最多或者总额最高的前3个,那不需要PARTITION BY,直接排序加限制就行:
SELECT merchant_id, COUNT(transaction_id) AS total_trans_count, SUM(amount) AS total_amount FROM transactions GROUP BY merchant_id -- 按总额降序,总额相同的话按交易数降序排 ORDER BY total_amount DESC, total_trans_count DESC LIMIT 3;
补充说明
- 用
ROW_NUMBER()的时候,同商家内的每条记录会得到唯一的序号,如果遇到金额相同的交易,只会留其中一条。要是想保留所有金额相同的交易(比如并列第一的都算前3),可以换成RANK()或者DENSE_RANK():RANK():相同金额的交易排名相同,但下一个不同金额的排名会跳号(比如1,1,3)DENSE_RANK():相同金额的排名相同,下一个不同金额的排名不会跳号(比如1,1,2)
内容的提问来源于stack exchange,提问作者Nicholas Goh
相关产品推荐
相关产品推荐

