Dybest set er din forespørgsel forkert til at begynde med. Brug UNION ALL
, ikke eller du ville fejlagtigt fjerne duplikerede poster. (Der er intet at sige, at sporet ikke kan skifte frem og tilbage mellem de samme e-mails.)UNION
Postgres-implementeringen for UNION ALL
returnerer værdier i sekvensen som tilføjet - så længe du ikke gør det tilføj ORDER BY
til sidst eller gør noget andet med resultatet.
Vær dog opmærksom på, at hver SELECT
returnerer rækker i vilkårlig rækkefølge, medmindre ORDER BY
er vedlagt. Der er ingen naturlig rækkefølge i tabeller.
Det samme er ikke sand for UNION
, som skal behandle alle rækker for at fjerne mulige dubletter. Der er forskellige måder at bestemme dubletter på, den resulterende rækkefølge af rækker afhænger af den valgte algoritme og er implementeringsafhængig og fuldstændig upålidelig - medmindre igen, ORDER BY
er tilføjet.
Så brug i stedet:
SELECT * FROM iter1
UNION ALL -- union all!
SELECT * FROM iter2;
For at få en pålidelig sorteringsrækkefølge og "simulere vækstrekorden", kan du spore niveauer som dette:
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 her
Gamle sqlfiddle
Til side:hvis old_email
er ikke defineret UNIQUE
på en eller anden måde kan du få flere stier. Du skal bruge en unik kolonne (eller kombination af kolonner) for at holde den utvetydig. Hvis alt andet fejler, kan du (ab-)bruge det interne tuple-id ctid
med det formål at skelne spor fra hinanden. Men du skal hellere bruge dine egne spalter. (Tilføjet eksempel i violinen.)
Overvej: