2014-11-19 5 views
2

Я пытаюсь написать запрос, который возвращает произвольный размерный образец данных. Я хотел бы сделать это, только выбрав n th строк, где n таково, что весь набор результатов максимально приближен к произвольному размеру.SELECT фиксированное количество строк путем равномерного пропуска строк

Я хочу, чтобы это работало в тех случаях, когда результирующий набор обычно был бы меньше произвольного размера. В таком случае весь результирующий набор должен быть возвращен.

Я нашел this question, где показано, как выбрать каждый n th Строка.


Вот то, что я до сих пор:

SELECT * FROM (
    SELECT *, ((row_number() OVER (ORDER BY "time")) 
       % ceil(count(*)::FLOAT/500::FLOAT)::BIGINT) AS rn 
    FROM data_raw) sa 
WHERE sa.rn=0; 

Это приводит к следующей ошибке:

ERROR: column "data_raw.serial" must appear in the GROUP BY clause or be used in an aggregate function Position: 23


Отсоединение расчет для n, как это работает:

SELECT * FROM (
    SELECT *, (row_number() OVER (ORDER BY "time")) 
       % 50 AS rn FROM data_raw) sa 
LIMIT 500; 


Я также попытался переместить вычисление в предложении WHERE:

SELECT * FROM (
    SELECT *, (row_number() OVER (ORDER BY "time")) AS rn 
    FROM data_raw) sa 
WHERE (sa.rn % ceil(count(*)::FLOAT/500::FLOAT)::BIGINT)=0; 

Это тоже приводит к ошибке:

ERROR: aggregate functions are not allowed in WHERE Position: 108


Кто-нибудь есть какие-либо идеи о том как, как исправить мой запрос или лучший способ сделать это?

Я также думал об использовании случайных чисел и вероятности выбора строк, но я предпочел бы сделать что-то детерминированное без возможности скрещивания.

+0

BTW, pg 9.4? Вы используете бета-версию? –

+0

Да, я использую 9.4. – Ian

ответ

1

Ошибка при первой попытке состоит в том, что вы не можете смешивать агрегатную функцию count(*) с неагрегированных выбор строк. Вы можете исправить это с помощью count() в окне заполнителя функции вместо:

SELECT * FROM (
    SELECT *, ((row_number() OVER (ORDER BY "time")) 
       % ceil(count(*) OVER()/500.0)::int) AS rn 
    FROM data_raw 
    ) sub 
WHERE sub.rn = 0;

Подробное описание здесь:

@Alexander имеет исправление для последней попытки.

1

Вы должны сделать что расчет подзапрос:

WHERE rn % (SELECT CEIL(COUNT(*)::FLOAT/500:FLOAT)::BIGINT FROM data_raw) = 0 

Таким образом, он больше не рассматривается в качестве агрегатной функции, но в качестве скалярного запроса.

Смежные вопросы