【问题标题】:How to get aggregate as a percentage of the total如何获得合计占总数的百分比
【发布时间】:2021-12-31 11:09:53
【问题描述】:

我有一张桌子:

CREATE TABLE schools (
    ID int,
    type varchar(255)
);

INSERT INTO schools (ID, type)
VALUES (1, NULL),
(2, 'primary'),
(3, 'secondary'),
(4, 's'),
(5, 'p'),
(5, 'p');
ID Type
1 NULL
2 'primary'
3 'secondary'
4 's'
5 'p'
5 'p'

我需要生成这样的表格:

Type Volume %
Primary 2 50
Secondary 2 50
Type      Volume %
Primary   2     50
Secondary 2     50

到目前为止,我使用查询获得了前两列:

SELECT CASE 
  WHEN type IN ('primary','p') THEN 'Primary'
  WHEN type IN ('secondary','s') THEN 'Secondary'
END Type,
count(distinct ID) as Volume
FROM t

我不知道如何以百分比形式获取音量。反复使用分区会不断引发聚合错误。有人可以解释一下我该怎么做吗?

另外,我希望百分比不包括 NULL,因此它有 50%。

【问题讨论】:

  • 只选择一个 DBMS 并删除多余的标签。指定精确的 DBMS 版本。
  • 我需要生成这样的表格 Volume 列是什么,它的值是如何从显示的 src 数据中产生的?

标签: sql aggregate partition


【解决方案1】:

使用SUM()窗口函数获取总数:

SELECT CASE 
         WHEN type IN ('primary','p') THEN 'Primary'
         WHEN type IN ('secondary','s') THEN 'Secondary'
       END type,
       COUNT(*) AS Volume,
       100 * COUNT(*) / SUM(COUNT(*)) OVER () AS percentage
FROM (SELECT DISTINCT ID, type FROM schools) s
WHERE type IS NOT NULL
GROUP BY 1;

请参阅demo

【讨论】:

    【解决方案2】:

    您可以使用以下查询

    SELECT Type,
           Volume,
           CAST(Volume AS Float) / SUM(Volume) OVER(PARTITION BY seq ORDER BY seq) * 100 AS '%'
    FROM
       (SELECT Type,
            COUNT(DISTINCT ID) AS Volume,
            RANK() OVER(ORDER BY (SELECT NULL)) as seq
       FROM
          (SELECT ID,
            CASE 
             WHEN type IN ('primary','p') THEN 'Primary'
             WHEN type IN ('secondary','s') THEN 'Secondary'
            END Type
           FROM t) t
       WHERE Type IS NOT NULL
       GROUP BY Type) t
    

    db<>fiddle中的演示

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多