[英]SQL (postgres) to join over a variable number of subselects
我有3张桌子:
orders
表引用具有shop.id
商店中已售出产品的product.id
。
我想创建一个sql视图,该视图选择每个商店的前10种产品。 因此,我希望结果表有10行(每个等级一个),并且列的数量与shop
表中商店的ID一样多,每列中有10个卖家。
获得每个商店的十大产品很容易。 通过重复并加入选择以从单个商店中获取固定数量的n个商店,这也很容易,但是我不知道如何在数量可变的商店中做到这一点。 我搜索了类似的示例,我的感觉是,使用通用表表达式应该可以实现此目的,但我不理解。
所以问题是:
如何在循环或类似构造中加入可变数量的子选择
示例结果应如下所示:
'RANK' 'Berlin' 'Hamburg' 'München'
1 2 3 4
2 . . .
. . . .
. . . .
9 . . .
10 . . x
这些数字是排名前10位的卖家的产品ID。 即创建的列类似于xx.product_id的“柏林”。
以下内容将生成您要查找的内容的转置:
select shop_id,
max(case when r = 1 then product_id else 0 end) as p_1,
max(case when r = 2 then product_id else 0 end) as p_2,
max(case when r = 3 then product_id else 0 end) as p_3,
max(case when r = 4 then product_id else 0 end) as p_4,
max(case when r = 5 then product_id else 0 end) as p_5,
max(case when r = 6 then product_id else 0 end) as p_6,
max(case when r = 7 then product_id else 0 end) as p_7,
max(case when r = 8 then product_id else 0 end) as p_8,
max(case when r = 9 then product_id else 0 end) as p_9,
max(case when r = 10 then product_id else 0 end) as p_10
from
(
select shop_id, product_id, sum(qty) as sales,
row_number() over (partition by shop_id order by sum(qty) desc) as r
from orders
group by shop_id, product_id
)group by shop_id
要进行转置,您可以使用crosstab ,但这需要您事先知道商店的数量。 数据库通常不设计为具有列数未知的表。 一种可能的方法是创建一个类似于此处的函数。
我认为您只需要具有聚合的row_number()
:
select s.*, o.product_id
from shops s join
(select shop_id, product_id, sum(qty) as qty,
row_number() over (partition by shop_id order by sum(qty) desc) as rnk
from orders o
group by shop_id, product_id
) o
on s.shop_id = o.shop_id
where rnk <= 10;
如果您想要有关产品的更多信息(而不是产品ID),则可以加入products
表。
您可以看一下交叉表功能来创建数据透视表。 AFAIK无法创建动态列,但请尝试一下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.