Zasadniczo Twoje zapytanie jest na początku nieprawidłowe. Użyj UNION ALL , a nie lub błędnie usuniesz zduplikowane wpisy. (Nie ma nic do powiedzenia, że szlak nie może przełączać się między tymi samymi e-mailami).UNION
Implementacja Postgres dla UNION ALL zwraca wartości w sekwencji jako dołączone - o ile nie dodaj ORDER BY na końcu lub zrób cokolwiek innego z wynikiem.
Pamiętaj jednak, że każdy SELECT zwraca wiersze w dowolnej kolejności, chyba że ORDER BY jest dołączony. W tabelach nie ma naturalnego porządku.
To samo nie prawda dla UNION , który musi przetworzyć wszystkie wiersze, aby usunąć ewentualne duplikaty. Istnieją różne sposoby określania duplikatów, wynikowa kolejność wierszy zależy od wybranego algorytmu i jest zależna od implementacji i całkowicie zawodna - chyba że ponownie ORDER BY jest dołączony.
Zamiast tego użyj:
SELECT * FROM iter1
UNION ALL -- union all!
SELECT * FROM iter2;
Aby uzyskać wiarygodną kolejność sortowania i „symulować rekord wzrostu”, możesz śledzić poziomy w następujący sposób:
WITH RECURSIVE all_emails AS (
SELECT *, 1 AS lvl
FROM audit_trail
WHERE old_email = 'example@sqldat.com'
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 tutaj
Stary sqlfiddle
Na bok:jeśli old_email nie jest zdefiniowany UNIQUE w pewien sposób możesz uzyskać wiele szlaków. Potrzebujesz unikalnej kolumny (lub kombinacji kolumn), aby zachować jednoznaczność. Jeśli wszystko inne zawiedzie, możesz (nad)użyć wewnętrznego identyfikatora krotki ctid w celu odróżnienia szlaków. Ale powinieneś raczej używać własnych kolumn. (Dodano przykład na skrzypcach.)
Rozważ: