检索每组中的三个最高值

Retrieving the three highest values in each group

有一个名为 'purchase_history' 的 table,其中包含如下所示的数据:

ID          product           price
123           abcd          1000
123           aaaa          2000
123           aaaa          3000
456           yyyy          50
456           bbbb          6000
456           cccc          450

我想为每个用户提取产品名称和最高 3 个价格的金额。 我希望每个用户只有一个输出行(即使购买少于 3 次),字段为 user_id、product_name_1、amount_1、product_name_2、amount_2、product_name_3、amount_3

有什么办法可以实现这个结果吗?

使用row_number()

select a.* from     
(select *, row_number() over(partition by id order by price desc) rn
from table_name
) a where a.rn=1

  select a1.* from table_name a1
  where a1.price=( select max(price) from table_name a2
                 where a1.id=a2.id)

或在 postgrey 中不同

SELECT DISTINCT ON (id) id, product,price
FROM table_name
ORDER BY id,price DESC

使用ROW_NUMBER() window函数过滤每个用户的前3个价格,然后使用条件聚合:

select t.id,
  max(case when t.rn = 1 then product end) product_name_1, 
  max(case when t.rn = 1 then price end) amount_1,
  max(case when t.rn = 2 then product end) product_name_2, 
  max(case when t.rn = 2 then price end) amount_2,
  max(case when t.rn = 3 then product end) product_name_3, 
  max(case when t.rn = 3 then price end) amount_3
from (
  select *, row_number() over (partition by id order by price desc) rn 
  from tablename
) t
where t.rn <= 3
group by t.id 

参见demo
结果:

| id  | product_name_1 | amount_1 | product_name_2 | amount_2 | product_name_3 | amount_3 |
| --- | -------------- | -------- | -------------- | -------- | -------------- | -------- |
| 123 | aaaa           | 3000     | aaaa           | 2000     | abcd           | 1000     |
| 456 | bbbb           | 6000     | cccc           | 450      | yyyy           | 50       |