2016-03-21 6 views
4

2つのタイムスタンプの間のすべてのポイントを返すクエリがあります。私が特に大きなタイムスライス(例えば1年)をすると、10000行が得られるかもしれません。私は決議(一日と言う)を求め、それらを1日に均等に配置し、〜365行を受け取ることができるようにしたいと考えています。ここに私の質問があります:PostgreSQLでの均等なデータサンプリング

SELECT * 
     FROM checkins 
     WHERE serial=${serial} AND created_at BETWEEN ${startTimestamp} AND ${endTimestamp} 
     ORDER BY created_at DESC 
     LIMIT ${limit} 
     OFFSET ${offset} 

Postgresを使って良い戦略をお考えですか?

答えて

0

これはトリックを行う必要がありますが、PG 9.4+を持っていると仮定すると:

SELECT * 
FROM checkins 
JOIN (
    -- The below returns 366 created_at values within the two time points, inclusive 
    SELECT precentile_disc(fraction/365.) WITHIN GROUP (ORDER BY created_at) 
    FROM checkins, generate_series(0, 365) f(fraction) 
    WHERE serial = ${serial} AND created_at BETWEEN ${startTimestamp} AND ${endTimestamp} 
) USING (created_at) 
ORDER BY created_at DESC;

percentile_disc() functionは値が供給に最も近いもので、指定した割合に応じてあなたにソートされたグループからの離散的な値を与えます分数。 generate_series()と組み合わせると、小数点以下のような値が得られます[0., 0.004, 0.008, ..., 1.]。次に、最終結果の値をcheckinsテーブルに戻します(値はcreated_atの値であり、端数ではありません)。 古いバージョンPGのについては

、あなたはそれを「手動」次のように行うことができます。

SELECT * 
FROM (
    SELECT *, rank() OVER (ORDER BY created_at) AS rnk 
    FROM checkins 
    WHERE serial = ${serial} AND created_at BETWEEN ${startTimestamp} AND ${endTimestamp} 
) sub 
WHERE rnk % extract(day from ${endTimestamp} - ${startTimestamp}) = 1 
ORDER BY created_at; 

これは、あなたstartTimestampendTimestamp間の各日の1行を与えるので、彼らは離れて一年ある場合365行を取得します。

+0

私はあなたが2番目のクエリが返す更新答え –

+0

を持っています。今、サブクエリに包ま – Patrick

+0

を参照してください;-) {その後、アップグレードする必要がありPG 9.3 :( –

関連する問題