Grundsätzlich ist Ihre Anfrage zunächst falsch. Verwenden Sie UNION ALL
, nicht oder Sie würden doppelte Einträge fälschlicherweise entfernen. (Es gibt nichts zu sagen, dass der Trail nicht zwischen denselben E-Mails hin und her wechseln kann.)UNION
Die Postgres-Implementierung für UNION ALL
gibt Werte in der angehängten Sequenz zurück - solange Sie dies nicht tun ORDER BY
hinzufügen am Ende oder machen Sie irgendetwas anderes mit dem Ergebnis.
Beachten Sie jedoch, dass jeder SELECT
gibt Zeilen in beliebiger Reihenfolge zurück, es sei denn ORDER BY
angehängt ist. Es gibt keine natürliche Reihenfolge in Tabellen.
Das Gleiche gilt nicht wahr für UNION
, die alle Zeilen verarbeiten muss, um mögliche Duplikate zu entfernen. Es gibt verschiedene Möglichkeiten, Duplikate zu ermitteln, die resultierende Reihenfolge der Zeilen hängt vom gewählten Algorithmus ab und ist implementierungsabhängig und völlig unzuverlässig - es sei denn, wieder ORDER BY
angehängt.
Verwenden Sie stattdessen:
SELECT * FROM iter1
UNION ALL -- union all!
SELECT * FROM iter2;
Um eine zuverlässige Sortierreihenfolge zu erhalten und "die Wachstumsaufzeichnung zu simulieren", können Sie Ebenen wie folgt verfolgen:
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 hier
Altes sqlfiddle
Nebenbei:if old_email
ist nicht definiert UNIQUE
In gewisser Weise können Sie mehrere Spuren erhalten. Sie benötigen eine eindeutige Spalte (oder eine Kombination von Spalten), um sie eindeutig zu halten. Wenn alles andere fehlschlägt, können Sie die interne Tupel-ID ctid
(missbrauchen) verwenden zum Zwecke der Unterscheidung von Spuren. Aber Sie sollten lieber Ihre eigenen Spalten verwenden. (Beispiel in der Geige hinzugefügt.)
Bedenken Sie: