-1

期待どおりに結果セットを返すクエリを Postgres で実行したいのですが (たとえば)、結果を少しシャッフルして、同じ値SELECT * FROM products ORDER BY created_at DESCを共有する連続した結果が多すぎないようにします。supplier_id

これは特に重要です。各サプライヤーからの製品はほぼ同時にインポートされる傾向がありcreated_at、結果も同じになるため、結果の数ページが 1 つのサプライヤーの製品にすぎないことがよくあるからです。

どうやって混ぜるの?

4

2 に答える 2

1

私が最終的にあなたの質問を正しく理解できれば、ウィンドウ関数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

ORDER BYin the句はオプションですが、final句OVERと同期するため、Postgres 9.1 を使用した私のテストでは実行速度が向上しました。ORDER BY

X同時に同じサプライヤからの行までが任意に選択されます。本当にランダムな選択が必要な場合は、句random()でさらに注文する必要があります。OVER

それ以外は、これは「ランダム化」または「再シャッフル」ではなく、余分な行を抑制することです。これらの行 (以上X) を表示する場合は、並べ替え順序を定義する必要があります。ただし、必然的に時系列が崩れます。

于 2013-02-12T15:39:52.640 に答える
0

私の理解では、結果を時系列で並べ替えたいと考えていますが、 の特定の値についてはcreated_at、 の異なる値は 1 つしかsupplier_idなく、並べ替えられたリストで十分に近いと仮定して、代わりに複数の値を使用する必要があります。

重要な問題はcreated_at、それが何であれ ( 1timestamptimestamp(0)未満の解像度を持つ、1 秒の解像度を持つ) の解像度が、並べ替え基準として直接使用すると高すぎることです。

代わりに、時間の範囲で並べ替えることができます。例えば:

ORDER BY (extract(epoch from created_at)/3600)::int, RANDOM()

最初にエントリが挿入された時間 (3600 秒) (70 年 1 月 1 日からの経過時間数として測定) で並べ替え、次にこの範囲内の結果を 2 次並べ替え (ランダム) でシャッフルします。同じ時間内に異なるサプライヤーが挿入される可能性がまだ小さすぎる場合は、数時間または数日にしてください。

于 2013-02-12T17:20:25.250 に答える