Проблема здесь заключается в вычислении элементов Top N на группу.
Предполагается, что у вас есть следующие данные в таблице sales
.
# select * from sales;
shopid | articleid | price
--------+-----------+-------
1 | 2 | 80
3 | 3 | 100
4 | 2 | 95
1 | 3 | 150
5 | 3 | 50
С помощью следующего запроса мы можем создать раздел для каждого ArticleId
select
ArticleID,
ShopID,
Price,
row_number() over (partition by ArticleID order by Price desc) as Price_Rank from sales;
Это приведет к:
articleid | shopid | price | price_rank
-----------+--------+-------+------------
2 | 4 | 95 | 1
2 | 1 | 80 | 2
3 | 1 | 150 | 1
3 | 3 | 100 | 2
3 | 5 | 50 | 3
Затем мы просто выберем 2 лучших элемента для каждого AritcleId:
select
ArticleID,
ShopID,
Price
from (
select
ArticleID,
ShopID,
Price,
row_number() over (partition by ArticleID order by Price desc) as Price_Rank
from sales) sales_rank
where Price_Rank <= 2;
, который В результате:
articleid | shopid | price
-----------+--------+-------
2 | 4 | 95
2 | 1 | 80
3 | 1 | 150
3 | 3 | 100
Наконец, мы можем использовать функцию crosstab
, чтобы получить ожидаемый сводный вид.
select *
from crosstab(
'select
ArticleID,
ShopID,
ShopID
from (
select
ArticleID,
ShopID,
Price,
row_number() over (partition by ArticleID order by Price desc) as Price_Rank
from sales) sales_rank
where Price_Rank <= 2')
AS sales_top_2("ArticleID" INT, "ShopID_1" INT, "ShopID_2" INT);
И результат:
ArticleID | ShopID_1 | ShopID_2
-----------+----------+----------
2 | 4 | 1
3 | 1 | 3
Примечание: вам может потребоваться позвонить CREATE EXTENSION tablefunc;
в случае, если вы получите ошибку function crosstab(unknown) does not exist
.