如果 rank() 在 sql 中重复某些值,如何从 6 个中选择前 5 个值?

how to choose top 5 values out of 6 if rank() repeats some values in sql?

task是为了

return the top 5 customer ids and their rankings based on their spend for each store.

只有 2 个表 - 付款表和客户表。共有2家门店。

对于 store_id = 2,rank() 给出重复的 1,2,2,3,4,5 值,即 6。我不知道如何使用 [=30= 选择 5 ] 代码。因为它实际上是 6 - 我不能“限制 5”

sql小提琴是 here。我无法让它执行 sqlfiddle 中的 row_number()。

我自己的查询:

with help2 as(
    select 
    store_id, 
    customer.customer_id, 
    sum(amount) as revenue
        
    from  customer inner join payment on 
    customer.customer_id = payment.customer_id
    where store_id = 2
    group by
    customer.customer_id
    order by revenue desc)              
    
    select 
    store_id, customer_id, revenue,
    
     rank() over(order by revenue desc) as ranking2
    
    from help2
    
     order by   ranking2  limit 6 -- i dont think there should be limit 6, this is hard coding

预期的答案是:

store_id  customer_id revenue ranking

2       526     221.55      1
2       178     194.61      2
2       137     194.61      2
2       469     177.60      3
2       181     174.66      4
2       259     170.67      5

简短的回答是使用 DENSE_RANK(),而不是 RANK()。这将为您提供与链接练习的样本输出相匹配的正确排名数字。

来自What’s the Difference Between RANK and DENSE_RANK in SQL?

Unlike DENSE_RANK, RANK skips positions after equal rankings. The number of positions skipped depends on how many rows had an identical ranking. For example, Mary and Lisa sold the same number of products and are both ranked as #2. With RANK, the next position is #4; with DENSE_RANK, the next position is #3.

WITH CustomerSpending AS (
    SELECT customer_id
    ,SUM(amount) as revenue
    FROM payment
    GROUP BY customer_id
)

,CustomerSpendingRanking AS (
    SELECT customer.store_id
    ,customer.customer_id
    ,CustomerSpending.revenue
    ,DENSE_RANK() OVER (PARTITION BY customer.store_id ORDER BY CustomerSpending.revenue DESC) as ranking
    FROM customer
    JOIN CustomerSpending
    ON customer.customer_id = CustomerSpending.customer_id
)

SELECT store_id
,customer_id
,revenue
,ranking
FROM CustomerSpendingRanking
WHERE ranking < 6;