以下SQL运行良好;它给出了我想要的计数和百分比结果:(如果需要,请使用EXTRACT(年|月|日...)):

SELECT YEAR(evt_date) AS yr, MONTH(evt_date) AS mth, DAY(evt_date) AS dy, COUNT(*) AS cnt,
       ROUND(COUNT(*)*100 / (SUM(COUNT(*)) OVER (PARTITION BY YEAR(evt_date), MONTH(evt_date))), 2) AS prct
   FROM my_data
   WHERE evt_date >= '2023-11-01'
   GROUP BY yr, mth, dy
   ORDER BY 1,2,3
   ;

但是,如果我在中引入汇总,我会得到cnt合计,但不会得到使用窗口表达式的百分比的合计.This must be a bug,但我没有办法报告它被修复:

SELECT YEAR(evt_date) AS yr, MONTH(evt_date) AS mth, DAY(evt_date) AS dy, COUNT(*) AS cnt,
       ROUND(COUNT(*)*100 / (SUM(COUNT(*)) OVER (PARTITION BY YEAR(evt_date), MONTH(evt_date))), 2) AS prct
   FROM my_data
   WHERE evt_date >= '2023-11-01'
   GROUP BY yr, ROLLUP (mth, dy)    -- ROLLUP does not give the the result I expect to see for the percentage column
   ORDER BY 1,2,3
   ;

有人知道为什么吗?我使用的是PostgreSQL V12.

我有一个有技巧的替代解决方案,但奇怪的是上面的那个不起作用:

WITH my_data(evt_date, foo) AS
      (SELECT '2023-11-01'::DATE, 'X' UNION
       SELECT '2023-11-01', 'Y' UNION
       SELECT '2023-11-02', 'X' UNION
       SELECT '2023-11-02', 'Y' UNION
       SELECT '2024-01-01', 'X' UNION
       SELECT '2024-01-01', 'Y' UNION
       SELECT '2024-01-01', 'Z' UNION
       SELECT '2024-01-02', 'X' UNION
       SELECT '2024-01-02', 'Y' UNION
       SELECT '2024-01-03', 'X' UNION
       SELECT '2024-01-03', 'Y' UNION
       SELECT '2024-01-03', 'Z' UNION
       SELECT '2024-01-03', 'W' 
      ),
    totals AS
      (SELECT YEAR(evt_date) AS yr, MONTH(evt_date) AS mth, DAY(evt_date) AS dy, COUNT(*) AS cnt,
               ROUND(COUNT(*)*100 / (SUM(COUNT(*)) OVER (PARTITION BY YEAR(evt_date), MONTH(evt_date))), 2) AS prct
           FROM my_data
           WHERE evt_date >= '2023-11-01'
           GROUP BY yr, mth, dy 
           ORDER BY 1,2,3 
      )
   SELECT yr, mth, dy, SUM(cnt) AS cnt, SUM(prct) AS prct --<-- Fake SUM() to be able to use ROLLUP
     FROM totals
     GROUP BY yr, ROLLUP (mth, dy)  --- Only way? for ROLLUP to handle the percentage column well
      ORDER BY 1,2,3
   

推荐答案

See example.
First, prct calculation can be before ROLLUP.

并且,您对(分区除以yr,mth)计算sum(),因此ROLLUP可以是(dy).

select yr,mth,dy,sum(prct) pct
from (
SELECT extract(year from evt_date) AS yr
   , extract(MONTH from evt_date) AS mth
   , extract(DAY from evt_date) AS dy
   , COUNT(*) AS cnt
   , ROUND(COUNT(*)*100 / 
         (SUM(COUNT(*)) 
           OVER (PARTITION BY extract(year from evt_date), extract(MONTH from evt_date)))
      , 2) AS prct
FROM my_data
WHERE evt_date >= '2023-11-01'
GROUP BY evt_date
)x
group by yr,mth,rollup(dy)
ORDER BY 1,2,3
;

输出

yr mth dy pct
2023 11 1 50.00
2023 11 2 50.00
2023 11 null 100.00
2024 1 1 33.33
2024 1 2 22.22
2024 1 3 44.44
2024 1 null 99.99

yr分区并汇总(mth,dy)

select yr,mth,dy,sum(prct) pct
from (
SELECT extract(year from evt_date) AS yr
   , extract(MONTH from evt_date) AS mth
   , extract(DAY from evt_date) AS dy
   , COUNT(*) AS cnt
   , ROUND(COUNT(*)*100 / 
         (SUM(COUNT(*)) 
           OVER (PARTITION BY extract(year from evt_date)))
      , 2) AS prct
FROM my_data
WHERE evt_date >= '2023-11-01'
GROUP BY evt_date
)x
group by yr,rollup(mth,dy)
ORDER BY 1,2,3
;

输出

yr mth dy pct
2023 11 1 50.00
2023 11 2 50.00
2023 11 null 100.00
2023 null null 100.00
2024 1 1 33.33
2024 1 2 22.22
2024 1 3 44.44
2024 1 null 99.99
2024 null null 99.99

我不知道这里的重点是什么.

Postgresql相关问答推荐

横向联接返回的行数太多

到第二天的Postgres计时器

一列引用两个不同的表

为什么32632投影中的几何图形并不完美?

PostgreSQL存储过程中不存在游标

单个WAL文件中的操作会影响哪些表和多少行

忽略 split_part 的第 n 个分隔符之后

PostgreSQL:在 select 和 group by 中使用不同的列不会导致错误

PostgreSQL 连接字符串的正则表达式

AGE Graph 实际上存储为 postgreSQL 表,对吧?如何检索该表(不是图表)?

如何在plpgsql中找到一行中的最大值?

联合所有 postgresql Select 子句保留顺序

如何将 postgres 数据库转换为 sqlite

从局域网访问 PostgreSQL 服务器

如果 Column1 不为空,则按 Column1 排序,否则按 Column2 排序

SqlAlchemy:多列的不同计数

如何在 postgresql 交叉表中用零替换空值

PGAdmin 编辑数据

Postgres DB 上的整数超出范围

PostgreSQL 多种认证方式