Eu tenho uma tabela simples com colunas col1, col2, col3. Todos não anuláveis.
Eu quero deletar todas as linhas onde a tupla (col1, col2) tem várias entradas. Background: uma restrição exclusiva para (col1, col2) deve ser adicionada.
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;
Acima funciona no PostgreSQL 10, mas falha em versões mais antigas.
Versões mais antigas me dizem esta mensagem de erro:
ERRO: a coluna "mytable.col1" deve aparecer na cláusula GROUP BY ou ser usada em uma função agregada
Como fazer isso funcionar no PG 9.3?
Você só precisa remover os parênteses ao redor das colunas em
group by (col1, col2)
. Isso funciona na versão 9.4 e anterior também:A razão pela qual ele falha (eu acho) é que, embora
(col1, col2)
seja equivalente arow(col1, col2)
, houve alguma inconsistência em como ele foi tratado nas várias cláusulas que foram corrigidas em 9.5. Nas versões anteriores, você poderia usar uma construção mais complexa emWHERE
:WHERE (SELECT (col1, col2)) IN ...
. Portanto, isso também deve funcionar no 9.3: