列必须出现在 GROUP BY 子句中或用于聚合函数中

gue*_*tli 3 postgresql postgresql-9.3 postgresql-10

我有一个包含 col1、col2、col3 列的简单表格。都不可为空。

我想删除元组 (col1, col2) 有多个条目的所有行。背景:应添加 (col1, col2) 的唯一约束。

drop table mytable;

create table mytable (
    col1 integer not null,
    col2 integer not null,
    col3 integer not null);

-- rows to delete
insert into mytable values (1, 1, 1);
insert into mytable values (1, 1, 2);

-- rows to keep
insert into mytable values (2, 2, 1);
insert into mytable values (2, 3, 2);



delete from mytable where 
(col1, col2) in  (
    select col1, col2 from mytable  
    group by (col1, col2) having  count(distinct col3) >1) ;

select * from mytable;
Run Code Online (Sandbox Code Playgroud)

以上适用于 PostgreSQL 10,但在旧版本上失败。

旧版本告诉我这个错误信息:

错误:列“mytable.col1”必须出现在 GROUP BY 子句中或用于聚合函数中

如何让它在 PG 9.3 上工作?

ype*_*eᵀᴹ 6

您只需要删除group by (col1, col2). 这也适用于 9.4 及更早版本:

delete from mytable  
where (col1, col2) in  (
    select col1, col2 from mytable  
    group by col1, col2                   -- <-- changed
    having  count(distinct col3) >1) ;
Run Code Online (Sandbox Code Playgroud)

它失败的原因(我认为)是 while(col1, col2)相当于row(col1, col2),在 9.5 中修复的各种条款中处理它的方式存在一些不一致。在以前的版本中,您可以在WHERE: 中使用更复杂的构造WHERE (SELECT (col1, col2)) IN ...。所以这也应该适用于 9.3:

delete from mytable
where (select (col1, col2)) in  (
    select (col1, col2) from mytable  
    group by (col1, col2) having  count(distinct col3) >1) ;
Run Code Online (Sandbox Code Playgroud)