Fondamentalmente, la tua domanda non è corretta per cominciare. Usa UNION ALL
, non o rimuoveresti erroneamente le voci duplicate. (Non c'è nulla da dire che il percorso non può passare avanti e indietro tra le stesse email.)UNION
L'implementazione di Postgres per UNION ALL
restituisce i valori nella sequenza come aggiunto, purché non aggiungi ORDER BY
alla fine o fare qualsiasi altra cosa con il risultato.
Attenzione però, che ogni SELECT
restituisce le righe in ordine arbitrario a meno che ORDER BY
è allegato. Non c'è un ordine naturale nelle tabelle.
Lo stesso non true per UNION
, che deve elaborare tutte le righe per rimuovere possibili duplicati. Esistono vari modi per determinare i duplicati, l'ordine delle righe risultante dipende dall'algoritmo scelto ed è dipendente dall'implementazione e completamente inaffidabile, a meno che, ancora una volta, ORDER BY
viene aggiunto.
Quindi usa invece:
SELECT * FROM iter1
UNION ALL -- union all!
SELECT * FROM iter2;
Per ottenere un ordinamento affidabile e "simulare il record di crescita", puoi tenere traccia dei livelli come questo:
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<>violino qui
Vecchio sqlfiddle
A parte:se old_email
non è definito UNIQUE
in qualche modo, puoi ottenere più percorsi. Avresti bisogno di una colonna univoca (o combinazione di colonne) per mantenerla univoca. Se tutto il resto fallisce, puoi (ab-)usare l'ID tupla interno ctid
allo scopo di distinguere le tracce. Ma dovresti piuttosto usare le tue colonne. (Aggiunto esempio nel violino.)
Considera: