Estou aprendendo Postgres (vindo do SQL Server), e esse erro realmente me confunde.
Aqui está o código com alguns dados de exemplo:
create table T (
ID serial primary key,
A varchar(1),
B varchar(1),
C varchar(1)
)
↑ Tabela de testes.
insert into T (A, B, C)
values('A', 'B', 'C'), ('A', 'B', 'C')
↑ Inserir duplicatas
delete from T
where ID in (
select t.ID
from ( select ID, row_number() over (partition by A,B,C order by A,B,C) as rn
from T) as t
where t.rn < (select max(t.rn) from t)
)
↑ Excluir duplicata mantendo a última entrada.
O problema está no (select max(t.rn) from t)
que estou assumindo que este é um erro noob relacionado a não conhecer a sintaxe do postgres quando se trata de referenciar colunas com aliases?
Em primeiro lugar,
partition by A,B,C order by A,B,C
não faz sentido. Como você pretende manter a "última" linha (ou seja, aquela com o maiorID
), você provavelmente quis dizer:Ainda assim , a sintaxe é inválida além disso. Essa expressão de subconsulta contém uma referência a uma coluna da consulta externa:
(select max(t.rn) from t)
. O escopo da subconsulta não inclui colunas da consulta externa, portantorn
, não é visível lá. Apenas as colunas da tabelat
são.Você pode usar um CTE para permitir a referência e tornar a sintaxe válida :
Ainda assim , a consulta é um absurdo perigoso. Não use isso!
Comparar com o maior número de linhas é um absurdo lógico, pois cada grupo de pares pode ter um número diferente de dupes. Apagaria muito mais do que deveria.
Mais simples e correto:
O que, por sua vez, pode ser obtido de forma mais barata como (assumindo todas as colunas
NOT NULL
!):"... onde existe um dupe com um ID maior" .
Relacionado: