PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

A ordem é preservada após UNION no PostgreSQL?


Basicamente, sua consulta está incorreta para começar. Use UNION ALL , não UNION ou você removeria incorretamente as entradas duplicadas. (Não há nada que diga que a trilha não pode alternar entre os mesmos e-mails.)

A implementação do Postgres para UNION ALL retorna valores na sequência como anexados - contanto que você não adicione ORDER BY no final ou faça qualquer outra coisa com o resultado.
Esteja ciente, porém, que cada SELECT retorna linhas em ordem arbitrária, a menos que ORDER BY é anexado. Não há ordem natural nas tabelas.

O mesmo é não true para UNION , que deve processar todas as linhas para remover possíveis duplicatas. Existem várias maneiras de determinar duplicatas, a ordem resultante das linhas depende do algoritmo escolhido e é dependente da implementação e completamente não confiável - a menos que, novamente, ORDER BY é anexado.

Então use em vez disso:
SELECT * FROM iter1
UNION ALL  -- union all!
SELECT * FROM iter2;

Para obter uma ordem de classificação confiável e "simular o registro de crescimento", você pode rastrear níveis como este:
WITH RECURSIVE all_emails AS (
   SELECT  *, 1 AS lvl
   FROM    audit_trail
   WHERE   old_email = '[email protected]'

   UNION ALL  -- union all!
   SELECT t.*, a.lvl + 1
   FROM   all_emails  a
   JOIN   audit_trail t ON t.old_email = a.new_email
)
TABLE  all_emails
ORDER  BY lvl;

db<>fiddle aqui
Antigo sqlfiddle

Além:se old_email não está definido UNIQUE de alguma forma, você pode obter várias trilhas. Você precisaria de uma coluna exclusiva (ou combinação de colunas) para mantê-la inequívoca. Se tudo mais falhar, você pode (ab-) usar o ID interno da tupla ctid com o propósito de distinguir as trilhas. Mas você deve usar suas próprias colunas. (Adicionado exemplo no violino.)

Considerar: