2016-03-27 61 views
0

可以說我有一個項目記錄的項目表,每個項目可以屬於一個或多個類別。每個類別有一個或多個項目PostgreSQL:選擇滿足限制條件的隨機記錄

我該如何選擇一個隨機列表唯一項目將匹配的條件,如從A類5項,從B類3項,從C類4項等並且還保留類別的順序,即A→B→C

查詢的sort_order和per category item_count存儲在另一個表中。

項目表相當大〜100萬行,滿足條件的項目可能會有相當大的差距。

回答

1

你可以嘗試這樣的事情:

SELECT item_id FROM (
    ((SELECT t.category,t.item_id from items t where t.category ='A' order by random() limit 5) 
    UNION 
    (SELECT t.category,t.item_id from items t where t.category ='B' order by random() limit 3) 
    UNION 
    (SELECT t.category,t.item_id from items t where t.category ='C' order by random() limit 4)) 
ORDER BY category 

我不能答應你,這將是快,但它應該工作。

1

我會傾向於用join要做到這一點,是這樣的:

select i.* 
from (select i.*, row_number() over (partition by category order by random()) as seqnum 
     from items i 
    ) i join 
    (select 'A' as category, 5 as num union all 
     select 'B' as category, 3 as num union all 
     select 'C' as category, 4 as num 
    ) l 
    on i.category = l.category 
where i.seqnum <= l.num; 

然而,這並沒有解決問題的唯一項目。所以,同一個項目可能會不止一次出現在列表中。假設有足夠的物品這一要求,我會首先選擇每個項目隨機分類,並按照同樣的邏輯:

select i.* 
from (select i.itemid, min(category) as category, 
      row_number() over (partition by min(category) 
           order by random() 
           ) as seqnum 
     from items i 
     group by i.itemid 
    ) i join 
    (select 'A' as category, 5 as num union all 
     select 'B' as category, 3 as num union all 
     select 'C' as category, 4 as num 
    ) l 
    on i.category = l.category 
where i.seqnum <= l.num; 

使用的min()是那種一個黑客,讓每一個項目類別。