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 = '[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 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ż: