PostgreSQL LIMIT через WINDOW - PullRequest
       14

PostgreSQL LIMIT через WINDOW

2 голосов
/ 21 марта 2012

Мне интересно, есть ли простой способ ограничить запрос верхними 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 Ответ

1 голос
/ 21 марта 2012

После комментария и его обдумывания, я думаю, следующий запрос делает то, что вы хотите.

Я выбираю первые 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, чтобы получить все строки для этих окон.

В целом это довольно сложный запрос.

...