我需要获得最少的数据。我当前的sql是
select min(count(*)) from table group by id ;
我期望获得变量计数(*)的最小计数。似乎不允许上面的查询。错误
aggregate function calls cannot be nested
被抛出。有没有办法使用任何交替方法实现这一目标?
答案 0 :(得分:5)
存在许多解决方案,如此处的答案数量所证明。 有趣的是,@ ahorse_with_no_name质疑每个人的表现。
SELECT MIN(count) FROM (SELECT COUNT(*) FROM table GROUP BY id) t;
它通常会产生以下计划:
Aggregate
-> HashAggregate
-> Seq Scan on table
SELECT COUNT(*) FROM table GROUP BY id ORDER BY 1 LIMIT 1;
对某些人来说感觉更自然,但遗憾的是会产生第二种情况:
Limit
-> Sort
Sort Key: (count(*))
-> HashAggregate
-> Seq Scan on table
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