如何统计组数?

How to count number of groups?

我有一个 table 如下:

id    g_n   val_name  
---------------------
1      a      "a"
2      a      "aa"
3      b      "123"
4      b      "asad"
5      c      "aas1"

我想计算不同 g_n 的数量。 (这里是3。)

我试过:

select count(*)
from table_t
group by g_n

但它给出了每组的项目数。

如何计算 distinct g_n 的数量?

使用count(distinct):

select count(distinct g_n)
from table_t;

没有必要使用 group by 聚合这个结果。

注意:这会忽略 NULL 值。如果你也想数,那么:

select count(distinct g_n) + max( (g_n is null)::int )

这也计算 g_n 中的 NULL 值(如果有则加 1):

SELECT count(*)             -- count(*) counts *all* rows
FROM  (SELECT DISTINCT ON (g_n) FROM tbl) sub;

子查询中的 SELECT 列表可以保持为空,因为外部 SELECT 中的 count(*) 无论如何都不考虑行值,只计算行数(这就是为什么它是比 count(expression)) 快。

它通常也比聚合表达式中的 DISTINCT 子句快:

SELECT count(DISTINCT g_n)  -- count(expression) ignores NULL values
FROM   tbl; 

但是要在大 table 中获得 真正快速的 少数 个不同 g_n 的计数,请效仿索引跳过扫描。一个基本索引就可以完成这项工作:

CREATE INDEX ON tbl (g_n);

然后:

WITH RECURSIVE t AS (
   (SELECT g_n FROM tbl ORDER BY 1 LIMIT 1)

   UNION ALL
   SELECT (SELECT g_n FROM tbl WHERE g_n > t.g_n ORDER BY 1 LIMIT 1)
   FROM   t
   WHERE  t.col IS NOT NULL
   )
SELECT count(g_n) FROM t;  -- ignores NULL

要同时计算可能的 NULL,有条件地添加 1:

...
SELECT count(g_n) + CASE WHEN EXISTS(SELECT FROM tbl WHERE g_n IS NULL) THEN 1 ELSE 0 END
FROM   t;

同样,CASE 表达式与 EXISTS 对于大 tables 比 Gordon 演示的聚合要快得多:max((g_n is null)::int).

参见:

  • Optimize GROUP BY query to retrieve latest row per user
  • Select first row in each GROUP BY group?