mysql 查找前3个排序行的总和,并检查总和是否大于1000

nbysray5  于 2023-01-08  发布在  Mysql
关注(0)|答案(5)|浏览(176)

我有一个transaction表,表中的列为senderreceiverdateamount。我想找到所有接收者的名称,这些接收者的记录总和至少为1000,且不超过3个交易。

    • 示例:**
sender, receiver, date, amount
A, B, 2020-01-01, 500
C, B, 2020-01-01, 500 
D, B, 2020-21-01, 200
A, C, 2021-01-01, 400
D, C, 2021-01-01, 60
A, D, 2021-01-01, 4000
C, A, 2019-01-01, 50
D, A, 2019-02-01, 50
B, A, 2019-03-01, 50
E, A, 2019-04-01, 50
    • 答复:**
B, D. Answer in sorted name order
    • 说明:**B仅在2次交易中收到1000。D仅在1次交易中收到〉1000。

我知道如何根据名称对记录进行分组,但不知道如何找到3条记录的总和,并检查是否超过1000条。

btqmn9zl

btqmn9zl1#

WITH cte AS (
    SELECT receiver, amount,
           ROW_NUMBER() OVER (PARTITION BY receiver ORDER BY amount DESC) rn
    FROM transaction 
)
SELECT receiver
FROM cte
WHERE rn <= 3
GROUP BY receiver
HAVING SUM(amount) >= 1000
jtw3ybtb

jtw3ybtb2#

您可以使用group by receiverGROUP_CONCAT()在逗号分隔的列表中按降序收集每个receiver的所有金额。
然后使用SUBSTRING_INDEX提取前3个金额,并将它们相加,以检查它们的总和是否等于或大于1000:

SELECT receiver
FROM (
  SELECT receiver, 
         COUNT(*) counter,
         GROUP_CONCAT(amount ORDER BY amount DESC) amounts
  FROM tablename       
  GROUP BY receiver
) t  
WHERE SUBSTRING_INDEX(amounts, ',', 1) +
      CASE WHEN counter > 1 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(amounts, ',', 2), ',', -1) ELSE 0 END +
      CASE WHEN counter > 2 THEN SUBSTRING_INDEX(SUBSTRING_INDEX(amounts, ',', 3), ',', -1) ELSE 0 END 
      >= 1000;

请参见demo
当然,这不能很好地缩放超过3个数量。

uyto3xhc

uyto3xhc3#

你可以使用mysql变量来计算行数,然后根据行数进行过滤,就像这样

set @current_client := '';
set @row_count = 0;
select receiver, sum(amount) as total from (select receiver,amount,  
case 
    when  @current_client = receiver then @row_count := @row_count+1 
    when @current_client !=  receiver THEN @row_count := 1 
end as tmp1,
case  when @current_client !=  receiver THEN @current_client := receiver end as tmp2,
@row_count as row_number 
FROM transaction  order by transaction.receiver asc, transaction.amount desc
) as tmp
where row_number <= 3
group by receiver
having total >= 1000

此处演示

h5qlskok

h5qlskok4#

以下内容适用于MySQL 8+(5.7不在原始问题或原始标签中)。
您可以使用row_number()按金额降序对事务处理进行排序。然后汇总:

select receiver
from (select t.*,
             row_number() over (partition by receiver order by amount desc) as seqnum
      from t
     ) t
where seqnum <= 3
group by receiver
having sum(amount) >= 1000;

在较早的版本中,您可能需要使用变量枚举行,因为数据中可能存在联系:

select receiver
from (select t.*,
             (@rn := if(@r = receiver, @rn + 1,
                        if(@r := receiver, 1, 1)
                       )
             ) as seqnum
      from (select t.* from t order by receiver, amount desc) t cross join
           (select @rn := 0, @r := '') params
     ) t
where seqnum <= 3
group by receiver
having sum(amount) >= 1000;
jjhzyzn0

jjhzyzn05#

WITH A AS (
SELECT receiver, amount, ROW_NUMBER() OVER(PARTITION BY receiver ORDER BY receiver) AS ranking
FROM transactions
)

SELECT receiver, sum(amount) as total_received
FROM A
WHERE ranking IN (1,2,3)
group by receiver
HAVING sum(amount) >= 1000

相关问题