Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PostgreSQL中,是否有使用窗口函数的WHERE COUNT()替代方法?_Sql_Postgresql - Fatal编程技术网

在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
                 );