我想在Postgres中運行一個按預期方式返回結果集的查詢(比如說SELECT * FROM products ORDER BY created_at DESC
),但將結果稍微調整一下,這樣就不會有太多連續的結果共享supplier_id
值。隨機化查詢結果共享某個屬性
這一點尤其重要,因爲每個供應商的產品往往大致同時進口,因此created_at
一樣,這意味着幾頁結果往往只有1個供應商的產品。
你怎麼混在一起的?
我想在Postgres中運行一個按預期方式返回結果集的查詢(比如說SELECT * FROM products ORDER BY created_at DESC
),但將結果稍微調整一下,這樣就不會有太多連續的結果共享supplier_id
值。隨機化查詢結果共享某個屬性
這一點尤其重要,因爲每個供應商的產品往往大致同時進口,因此created_at
一樣,這意味着幾頁結果往往只有1個供應商的產品。
你怎麼混在一起的?
如果我終於明白你的問題吧,window function row_number()
應該做的工作,用正確的PARTITION
:
SELECT *
FROM (
SELECT *, row_number() OVER (PARTITION BY created_at, supplier_id
ORDER BY created_at DESC) AS rn
FROM products
) a
WHERE rn <= X
ORDER BY created_at DESC
的OVER
子句中的ORDER BY
是可選的,但它在我和Postgres的測試,加快執行9.1,因爲它與最終的ORDER BY
條款同步。
最多可以同時從同一供應商處選擇X
行。如果您需要真正的隨機選擇,則必須在OVER
子句中額外訂購random()
。
除此之外,這不是「隨機化」或「重新洗牌」,而是抑制多餘的行。如果要顯示這些行(超過X
),則必須按排序順序定義位置。儘管如此,它將不可避免地破壞時間順序。
我的理解是要以時間順序排序結果,但對於created_at
特定的值,只有一個supplier_id
不同的價值,你會希望有一些相反,假設他們在也非常接近排序列表。直接作爲排序標準時
的關鍵問題將是的created_at
分辨率,無論是它(timestamp
具有亞秒級分辨率,timestamp(0)
將有一秒的分辨率)太高。
您可以嘗試按照時間範圍進行排序。例如:
ORDER BY (extract(epoch from created_at)/3600)::int, RANDOM()
會命令首先由小時(3600秒)插入的條目,如自1/1/70的經過的小時數來測量,然後洗牌內部這一範圍的結果與次級排序(隨機)。如果在同一個小時內插入不同供應商的可能性仍然很小,則需要幾個小時或幾天。
你是否希望每個供應商中只有一個出現在這個洗牌數據集中,或者重複供應商都可以,只要他們不是「太頻繁」? – 2013-02-12 15:05:52
您是否縮進以**隨機**訂購 – frictionlesspulley 2013-02-12 15:06:31
重複可以,但不會太頻繁。我只是不希望具有相同'supplier_id'的X產品連續出現。 – Avishai 2013-02-12 15:07:39