Иерархия данных свертки в postgresql 8.0?

#postgresql #group-by #rollup #postgresql-8.0

#postgresql #группировать по #свертка #postgresql-8.0

Вопрос:

Я пытаюсь выполнить свертку в postgresql 8.0. В последней версии postgresql у нас есть функция свертки, но как реализовать свертку в postgresql 8.0? У кого-нибудь есть опыт работы с таким же?

Я попробовал следующее

 SELECT
    EXTRACT (YEAR FROM rental_date) y,
    EXTRACT (MONTH FROM rental_date) M,
    EXTRACT (DAY FROM rental_date) d,
    COUNT (rental_id)
FROM
    rental
GROUP BY
    ROLLUP (
        EXTRACT (YEAR FROM rental_date),
        EXTRACT (MONTH FROM rental_date),
        EXTRACT (DAY FROM rental_date)
    );
  

Но получаю следующую ошибку:

 42883: function rollup( integer, integer, integer) does not exist
  

следует из http://www.postgresqltutorial.com/postgresql-rollup /

Комментарии:

1. Postgres 8.0 давно мертва и забыта. Для использования вам нужен как минимум Postgres 9.5 (выпущен через 11 лет после версии 8.0) rollup

Ответ №1:

Как GROUP BY ROLLUP было введено в версии 9.5, у запроса нет шансов сработать. Но если вы подумаете о том, что это делает, в вашем случае должно быть очень легко придумать версию, дающую тот же результат.

В принципе, вы хотите иметь:

  1. общая сумма
  2. сумма в год
  3. и сумма в месяц
  4. для ежедневных подсчетов

Я написал выше особым образом, чтобы стало ясно, что вам на самом деле нужно:

  1. производить ежедневные подсчеты
  2. генерировать сумму за месяц из ежедневных подсчетов
  3. генерировать сумму за год из ежемесячных сумм или ежедневных подсчетов
  4. генерировать итоговые данные из годовых сумм, месячных сумм или ежедневных подсчетов
  5. UNION ALL из вышеперечисленного в нужном порядке

Поскольку по умолчанию для GROUP BY ROLLUP сначала записывается общее количество, а затем отдельные наборы группировок с NULLS LAST , следующий запрос будет выполнять то же самое:

 WITH
    daily AS (
        SELECT EXTRACT (YEAR FROM rental_date) y, EXTRACT (MONTH FROM rental_date) M, EXTRACT (DAY FROM rental_date) d, COUNT (rental_id) AS count
        FROM rental
        GROUP BY 1, 2, 3
    ),
    monthly AS (
        SELECT y, M, NULL::double precision d, SUM (count) AS count
        FROM daily
        GROUP BY 1, 2
    ),
    yearly AS (
        SELECT y, NULL::double precision M, NULL::double precision d, SUM (count) AS count
        FROM monthly
        GROUP BY 1
    ),
    totals AS (
        SELECT NULL::double precision y, NULL::double precision M, NULL::double precision d, SUM (count) AS count
        FROM yearly
    )
SELECT * FROM totals
UNION ALL
SELECT * FROM daily
UNION ALL
SELECT * FROM monthly
UNION ALL
SELECT * FROM yearly
;
  

Вышесказанное работает с PostgreSQL 8.4 . Если у вас даже нет этой версии, мы должны вернуться к старой школе UNION без повторного использования данных агрегирования:

 SELECT NULL::double precision y, NULL::double precision M, NULL::double precision d, COUNT (rental_id) AS count
FROM rental
UNION ALL
SELECT EXTRACT (YEAR FROM rental_date) y, EXTRACT (MONTH FROM rental_date) M, EXTRACT (DAY FROM rental_date) d, COUNT (rental_id) AS count
FROM rental
GROUP BY 1, 2, 3
UNION ALL
SELECT EXTRACT (YEAR FROM rental_date) y, EXTRACT (MONTH FROM rental_date) M, NULL::double precision d, COUNT (rental_id) AS count
FROM rental
GROUP BY 1, 2
UNION ALL
SELECT EXTRACT (YEAR FROM rental_date) y, NULL::double precision M, NULL::double precision d, COUNT (rental_id) AS count
FROM rental
GROUP BY 1
;
  

Комментарии:

1. общие табличные выражения ( with ... ) также не поддерживаются в Postgres 8.0

2. Я предполагал, что последняя версия в серии 8.x: postgresql.org/docs/8.4/sql-select.html но никаких проблем…