0

我正在尝试在 postgresql 8.0 中汇总。在 postgresql 的最新版本中,我们有 ROLLUP 功能,但是如何在 postgresql 8.0 中实现 rollup 呢?有人有同样的经验吗?

我尝试了以下

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/

4

1 回答 1

0

正如在9.5 版本GROUP BY ROLLUP中引入的那样,查询没有机会工作。但是,如果您考虑一下它的作用,那么在您的情况下应该很容易想出一个产生相同结果的版本。

基本上,您希望拥有:

  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
;
于 2019-04-08T05:41:48.550 回答