2016-03-21 1 views
4

У меня есть запрос, который возвращает все точки между двумя метками времени. Если я делаю особенно большой таймлис (скажем, 1 год), я могу получить 10000 строк. Я хочу иметь возможность запросить разрешение (скажем, 1 день) и равномерно распределить их на 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 дает дискретное значение из отсортированных групп по фракции, указанных с значением является ближайшим к пpилaгaeмомy доля. В комбинации с generate_series() вы получаете серию таких значений на фракциях [0., 0.004, 0.008, ..., 1.]. Затем вы присоединяете эти значения (значения created_at, а не фракции) к таблице checkins для окончательного результата.

Для старых версий ПГ, вы можете сделать это «вручную», как это:

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; 

Это дает 1 строку на каждый день между startTimestamp и endTimestamp, так что если они в один год вы получите 365 строк.

+0

Я только PG 9,3 :( –

+0

Вы должны обновить, то {;-) Смотрите обновленный ответ – Patrick

+0

, что 2-й запрос возвращает: «оконные функции не допускается, где положение» –