在PostgreSQL中,是否有使用窗口函数的WHERE COUNT()替代方法?
我尝试按两列进行分组,并仅按第一列不重复的记录筛选结果。然后,结果值可以分别用作键和值。 我用两种不同的方法达到了预期的效果,但似乎都不够 为了简化问题,我将用一个只有两列和几个值的表来总结:在PostgreSQL中,是否有使用窗口函数的WHERE COUNT()替代方法?,sql,postgresql,Sql,Postgresql,我尝试按两列进行分组,并仅按第一列不重复的记录筛选结果。然后,结果值可以分别用作键和值。 我用两种不同的方法达到了预期的效果,但似乎都不够 为了简化问题,我将用一个只有两列和几个值的表来总结: create table example ( foreign_key integer, item_value text ); insert into example (foreign_key, item_value) values (1, 'a'), (1, 'a'), (1, 'b'
create table example (
foreign_key integer,
item_value text
);
insert into example (foreign_key, item_value) values
(1, 'a'), (1, 'a'), (1, 'b'), (1, 'a'), (2, 'a'), (2, 'a'), (2, 'a'),
(3, 'c'), (3, 'a'), (3, 'a'), (4, 'a'), (4, 'c'), (4, 'e'), (5, 'b');
第一种方法是使用CTE和WITH子句,然后在WHERE子句中使用子查询进行过滤:
第二种方法是在FROM子句中使用带有OVER window函数的子查询:
两种方法都返回相同的结果,对所使用的输入正确:
foreign_key item_value
2 "a"
5 "b"
但它们似乎过于昂贵,而且阅读起来不那么愉快 有没有更好的方法达到同样的效果?您可以尝试使用exists
这似乎是一个简单的组,通过计算不同的值:
select foreign_key, max(item_value) as item_value
from example
group by foreign_key
having count(distinct item_value) = 1
order by foreign_key;
我希望有这样的情况:
select e.*
from (select e.*, count(*) over (partition by foreign_key) as cnt
from example e
) e
where cnt = 1;
然而,聚合方法也是可行的。检查哪个更快会很有趣
如果保证行是唯一的,则不存在以下替代方法:
这两种方法都允许您轻松返回给定行中的所有列。但它们似乎过于昂贵-它们实际上昂贵吗?执行计划是什么样子的?你有正确的索引吗?你为什么要按1,2分组?编辑:啊,我发现它是顺序符号:
select distinct foreign_key,item_value
from example e where exists (select 1 from example e1 where e.foreign_key=e1.foreign_key having count(distinct item_value)=1)
select foreign_key, max(item_value) as item_value
from example
group by foreign_key
having count(distinct item_value) = 1
order by foreign_key;
select e.*
from (select e.*, count(*) over (partition by foreign_key) as cnt
from example e
) e
where cnt = 1;
select e.*
from example e
where not exists (select 1
from example e2
where e2.foreign_key = e.foreign_key and e2.value <> e.value
);