2015-03-31 35 views
0

的我有3個表:SQL(postgres的)加入在可變數目子選擇

  • 店鋪{ 'ID', 'NAME'}
  • 產物{ 'ID', 'NAME'}
  • 訂單{ 'SHOP_ID', 'PRODUCT_ID', '數量'}

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名賣家的產品ID。 也就是說這些列被創建爲xx.product_id,如'Berlin'。

回答

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; 

如果你想爲產品(比產品標識更多)的更多信息,那麼你可以在products表連接。

+0

這給了我的商店十個產品,但在行而不是列。 – Peter 2015-03-31 14:19:16

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的功能。

+0

這會得到數據,但我真的很想知道如何儘可能地將這些數據置換。 – Peter 2015-03-31 14:29:47

0

你可以看看crosstab函數來創建數據透視表。 AFAIK不可能創建動態列,但試試看。