如何获得合计占总数的百分比

Posted

技术标签:

【中文标题】如何获得合计占总数的百分比【英文标题】: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 数据中产生的? 【参考方案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中的演示

【讨论】:

以上是关于如何获得合计占总数的百分比的主要内容,如果未能解决你的问题,请参考以下文章

SQL:您如何在列中显示占总数的百分比?

按组占总数的百分比

BigQuery Legacy SQL(子查询?)中占总数的百分比

使用 groupby 的 Pandas 占总数的百分比

百分比行占总数,其中每行由 group by 子句确定

当查询有 GROUP BY 时如何获得总数的百分比?