PostgreSQL得到最少的计数(*)?

时间:2014-11-21 11:36:55

标签: sql postgresql

我需要获得最少的数据。我当前的sql是

select min(count(*)) from table group by id ;

我期望获得变量计数(*)的最小计数。似乎不允许上面的查询。错误

aggregate function calls cannot be nested

被抛出。有没有办法使用任何交替方法实现这一目标?

4 个答案:

答案 0 :(得分:5)

存在许多解决方案,如此处的答案数量所证明。 有趣的是,@ ahorse_with_no_name质疑每个人的表现。

子查询方法

SELECT MIN(count) FROM (SELECT COUNT(*) FROM table GROUP BY id) t;

它通常会产生以下计划:

Aggregate
   ->  HashAggregate
         ->  Seq Scan on table

ORDER / LIMIT方法

SELECT COUNT(*) FROM table GROUP BY id ORDER BY 1 LIMIT 1;

对某些人来说感觉更自然,但遗憾的是会产生第二种情况:

 Limit
   ->  Sort
         Sort Key: (count(*))
         ->  HashAggregate
              ->  Seq Scan on table

CTE方法

WITH cte AS (SELECT count(*) FROM table GROUP BY id) SELECT MIN(count) FROM cte;

它与子查询非常相似,只是计划显示CTE已被扫描(如果表格很大,则可以实现)。

 Aggregate
   CTE cte
     ->  HashAggregate
           ->  Seq Scan on table
   ->  CTE Scan on cte

窗口聚合函数方法

或者,您可以使用与LIMIT结合的窗口聚合函数,并避免第二种排序。

SELECT MIN(COUNT(*)) OVER () FROM table GROUP BY id LIMIT 1;

它产生一个等同于子查询方法的计划(如果我们认为LIMIT 1几乎是免费的)。

 Limit
   ->  WindowAgg
         ->  HashAggregate
               ->  Seq Scan on table

答案 1 :(得分:4)

您需要将其包含在子选择中:

select min(cnt)
from (
  select id, count(*) as cnt
  from the_table
  group by id
) t
;

答案 2 :(得分:2)

我会在没有子查询的情况下这样做:

select count(*)
from table t
group by id
order by count(*) desc
limit 1;

我实际上想要使用distinct on找到解决方案(Postgres特定)。以下是诀窍:

select distinct on (case when id = id then null end) count(*)
from table t
group by id
order by (case when id = id then null end) , count(*) desc;

奇怪的case表达式是因为()不允许distinct on。并且,您无法在order by中使用常量。 case表达式是一种允许某些的技巧,它不是真正使用的,但只需要获得一行。

答案 3 :(得分:0)

with cte as (
select count(*)  count from table group by id 
)
select min(count) from cte