繁体   English   中英

SQL(postgres)联接可变数量的子选择

[英]SQL (postgres) to join over a variable number of subselects

我有3张桌子:

  • 商店{'ID','NAME'}
  • 产品{'ID','NAME'}
  • 订单{'SHOP_ID','PRODUCT_ID','QTY'}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM