V zásadě je váš dotaz na začátku nesprávný. Použijte UNION ALL
, nikoli nebo byste nesprávně odstranili duplicitní položky. (Není nic, co by říkalo, že stezka nemůže přepínat tam a zpět mezi stejnými e-maily.)UNION
Implementace Postgres pro UNION ALL
vrátí hodnoty v připojené sekvenci – pokud to neděláte přidat ORDER BY
na konci nebo s výsledkem udělejte cokoli jiného.
Uvědomte si však, že každý SELECT
vrátí řádky v libovolném pořadí, pokud není ORDER BY
je připojeno. V tabulkách neexistuje přirozený řád.
Totéž ne true pro UNION
, který musí zpracovat všechny řádky, aby odstranil případné duplikáty. Existují různé způsoby, jak určit duplikáty, výsledné pořadí řádků závisí na zvoleném algoritmu a je závislé na implementaci a zcela nespolehlivé - pokud opět ORDER BY
je připojeno.
Takže místo toho použijte:
SELECT * FROM iter1
UNION ALL -- union all!
SELECT * FROM iter2;
Chcete-li získat spolehlivé pořadí řazení a „simulovat záznam růstu“, můžete úrovně sledovat takto:
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 zde
Staré sqlfiddle
Aside:if old_email
není definováno UNIQUE
nějakým způsobem můžete získat více cest. Potřebovali byste jedinečný sloupec (nebo kombinaci sloupců), aby byl jednoznačný. Pokud vše ostatní selže, můžete (ab-) použít interní ID n-tice ctid
za účelem odlišení stop od sebe. Raději ale použijte vlastní sloupce. (Přidán příklad do houslí.)
Zvažte: