我有3张桌子:
orders
表格引用product.id
表示已在shop.id
商店销售的产品。
我想创建一个sql视图,每个商店选择前10个产品。因此,我希望结果表有10行(每个等级一个)和shop
表中存在商店ID的列数,每列中有10个卖家。
获得每个商店的十大产品很容易。通过重复和加入选择从单个商店获得这个,它也很容易得到固定数量的n个商店,但我不知道如何为不同数量的商店做这个。 我搜索了类似的例子,我的感觉是,这应该可以通过公用表表达式来实现,但我没有得到它。
所以问题是:
如何在循环或类似构造中加入可变数量的子选择
示例结果如何:
'RANK' 'Berlin' 'Hamburg' 'München'
1 2 3 4
2 . . .
. . . .
. . . .
9 . . .
10 . . x
其中数字是前10名卖家的产品编号。 即这些列的创建方式与xx.product_id一样为' Berlin'。
答案 0 :(得分:1)
以下内容产生了您正在寻找的转置:
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,但这需要您事先了解商店数量。数据库通常不会设计为具有未知列数的表。一种可能的方法是创建一个类似于here的函数。
答案 1 :(得分:0)
我认为你只想要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
表。
答案 2 :(得分:0)
您可以查看crosstab函数来创建数据透视表。 AFAIK无法创建动态列,但请试一试。