Postgresql 8.0中的汇总数据层次结构?

时间:2019-04-08 00:34:01

标签: postgresql group-by rollup postgresql-8.0

我正在尝试在PostgreSQL 8.0中进行汇总。在最新版本的postgresql中,我们具有ROLLUP函数,但是如何在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 个答案:

答案 0 :(得分:0)

version 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
;