Eu preciso recuperar todas as linhas de uma tabela onde 2 colunas combinadas são todas diferentes. Então, eu quero todas as vendas que não têm outras vendas que aconteceram no mesmo dia pelo mesmo preço. As vendas únicas com base no dia e preço serão atualizadas para um status ativo.
Então, eu estou pensando:
UPDATE sales
SET status = 'ACTIVE'
WHERE id IN (SELECT DISTINCT (saleprice, saledate), id, count(id)
FROM sales
HAVING count = 1)
Mas meu cérebro dói ir além disso.
sql
postgresql
sql-update
duplicates
distinct
sheats
fonte
fonte
Se você reunir as respostas até o momento, limpar e melhorar, chegaria a esta consulta superior:
O que é muito mais rápido que qualquer um deles. Nukes o desempenho da resposta atualmente aceita pelo fator 10 - 15 (nos meus testes no PostgreSQL 8.4 e 9.1).
Mas isso ainda está longe de ser o ideal. Use uma
NOT EXISTS
(anti-) semi-junção para obter um desempenho ainda melhor.EXISTS
é SQL padrão, existe desde sempre (pelo menos desde o PostgreSQL 7.2, muito antes da pergunta) e se encaixa perfeitamente nos requisitos apresentados:db <> mexer aqui
Old SQL Fiddle
Chave exclusiva para identificar a linha
Se você não tiver uma chave primária ou exclusiva para a tabela (
id
no exemplo), poderá substituir a coluna do sistemactid
pela finalidade desta consulta (mas não por outras finalidades):Toda tabela deve ter uma chave primária. Adicione um se você ainda não o tiver. Sugiro uma
serial
ou umaIDENTITY
coluna no Postgres 10+.Relacionado:
Como isso é mais rápido?
A subconsulta na
EXISTS
anti-semi-junção pode parar de avaliar assim que o primeiro dupe for encontrado (não faz sentido procurar mais). Para uma tabela base com poucas duplicatas, isso é levemente mais eficiente. Com muitas duplicatas, isso se torna muito mais eficiente.Excluir atualizações vazias
Para linhas que já possuem
status = 'ACTIVE'
essa atualização, isso não mudaria nada, mas ainda assim, insira uma nova versão de linha a custo total (pequenas exceções se aplicam). Normalmente, você não quer isso. Adicione outraWHERE
condição, como demonstrado acima, para evitar isso e torná-lo ainda mais rápido:Se
status
estiver definidoNOT NULL
, você pode simplificar para:O tipo de dados da coluna deve suportar o
<>
operador. Alguns tipos comojson
não. Vejo:Diferença sutil no manuseio de NULL
Esta consulta (diferente da resposta atualmente aceita por Joel ) não trata valores NULL como iguais. As duas linhas a seguir
(saleprice, saledate)
serão classificadas como "distintas" (embora pareçam idênticas ao olho humano):Também passa em um índice exclusivo e quase em qualquer outro lugar, já que os valores NULL não comparam iguais de acordo com o padrão SQL. Vejo:
OTOH,
GROUP BY
,DISTINCT
ouDISTINCT ON ()
valores mimo nulo como igual. Use um estilo de consulta apropriado, dependendo do que você deseja alcançar. Você ainda pode usar essa consulta mais rápida com emIS NOT DISTINCT FROM
vez de=
em qualquer uma ou todas as comparações, para tornar a comparação NULL igual. Mais:Se todas as colunas comparadas estiverem definidas
NOT NULL
, não haverá espaço para discordância.fonte
count(*)
é mais eficiente quecount(<expression>)
. Apenas tente. O Postgres possui uma implementação mais rápida para essa variante da função agregada. Talvez você esteja confundindo o Postgres com outros RDBMS?O problema com sua consulta é que, ao usar uma cláusula GROUP BY (que você basicamente usa distinta), você pode usar apenas colunas que agrupa ou agrega funções. Você não pode usar o ID da coluna porque existem valores potencialmente diferentes. No seu caso, sempre há apenas um valor por causa da cláusula HAVING, mas a maioria dos RDBMS não é inteligente o suficiente para reconhecer isso.
No entanto, isso deve funcionar (e não precisa de associação):
Você também pode usar MAX ou AVG em vez de MIN, é importante usar apenas uma função que retorne o valor da coluna se houver apenas uma linha correspondente.
fonte
Desejo selecionar os valores distintos de uma coluna 'GrondOfLucht', mas eles devem ser classificados na ordem em que são fornecidos na coluna 'classificação'. Não consigo obter os valores distintos de apenas uma coluna usando
Ele também fornecerá a coluna 'classificação' e, como 'GrondOfLucht' AND 'classificar' não é exclusivo, o resultado será TODAS as linhas.
use o GROUP para selecionar os registros de 'GrondOfLucht' na ordem dada por 'classificação
fonte
Se o seu DBMS não suportar distintos com várias colunas como esta:
A seleção múltipla em geral pode ser executada com segurança da seguinte maneira:
Como isso pode funcionar na maioria dos DBMS, espera-se que seja mais rápido que agrupar por solução, pois você está evitando a funcionalidade de agrupamento.
fonte