Агрегат PostgreSQL или оконная функция для возврата только последнего значения - PullRequest
7 голосов
/ 30 ноября 2011

Я использую статистическую функцию с предложением OVER в PostgreSQL 9.1 и хочу вернуть только последнюю строку для каждого окна. Оконная функция last_value() звучит так, как будто она может делать то, что я хочу, но это не так. Он возвращает строку для каждой строки в окне, тогда как я хочу только одну строку на окно

Упрощенный пример:

SELECT a, some_func_like_last_value(b) OVER (PARTITION BY a ORDER BY b)
FROM
(
    SELECT 1 AS a, 'do not want this' AS b
    UNION SELECT 1, 'just want this'
) sub

Я хочу, чтобы это вернуло одну строку:

1, 'just want this'

1 Ответ

14 голосов
/ 30 ноября 2011

DISTINCT плюс оконная функция

Добавить предложение DISTINCT:

SELECT DISTINCT a
     , last_value(b) OVER (PARTITION BY a ORDER BY b
                           RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM  (
   VALUES
     (1, 'do not want this')
    ,(1, 'just want this')
   ) sub(a, b);

Подробнее о DISTINCT:

Проще и быстрее с DISTINCT ON

PostgreSQLтакже имеет это расширение стандарта SQL:

SELECT DISTINCT ON (a)
       a, b
FROM  (
   VALUES
     (1, 'do not want this')
   , (1, 'just want this')
   ) sub(a, b)
ORDER  BY a, b DESC;

Подробнее о DISTINCT ON и, возможно, более быстрых альтернативах:

Простой случай с простым агрегатом

Если ваш случай на самом деле так же прост, как ваша демонстрация (и вам не нужны дополнительные столбцы из этого последнегострока), простая агрегатная функция будет проще:

SELECT a, max(b)
FROM  (
   VALUES
     (1, 'do not want this')
   , (1, 'just want this')
   ) sub(a, b)
GROUP  BY a;
...