PostgreSQL LIMIT через ОКНО
Мне интересно, есть ли простой способ ограничить запрос верхними n окнами.
т.е. скажи у меня что то типа
SELECT field1
,field2
,field3
,sum(field2) over (partition by field1) sum2
,sum(field3) over (partition by field1) sum3
FROM table1
GROUP BY field1, field2, field3
ORDER BY sum2 DESC LIMIT 100
Приведенный выше запрос возвращает первые 100 записей, а не первые 100 окон (что имеет смысл)
То, что я хочу получить, это первые 100 окон sum2, хотя в этом окне может быть несколько строк. Так что я мог бы получить 400 записей, но только первые 100 окон.
Надеюсь, это имеет смысл.
1 ответ
После комментария и обдумывания, я думаю, следующий запрос делает то, что вы хотите.
Я выбираю первые 100 "окон", полученных в результате запроса, и возвращаю все строки, попадающие в эти окна. Поскольку окна разделены field1
это эффективно 100 различных значений field1
с наибольшим sum2
, Для связи на sum2
чем больше field1
выигрывает в моем запросе (вы не указали).
WITH x AS (
SELECT field1
,field2
,field3
,sum(field2) over w sum2
,sum(field3) over w sum3
FROM table1
GROUP BY field1, field2, field3
WINDOW w AS (PARTITION BY field1)
)
, y AS (
SELECT field1
FROM x
GROUP BY sum2, field1
ORDER BY sum2 DESC, field1 DESC
LIMIT 100
)
SELECT x.*
FROM y
JOIN x USING (field1)
ORDER BY sum2 DESC, field1 DESC, field2 DESC, field3 DESC;
Важнейшим моментом является генерация агрегированных значений в CTE, выбор из 100 выигрышных окон из тех, что в другом CTE (это также можно сделать с помощью DISTINCT, я выбрал GROUP BY
/ ORDER BY
) и присоедините результат к первому CTE, чтобы получить все строки для этих окон.
В целом, это довольно сложный запрос.