Kortom, uw vraag is om te beginnen onjuist. Gebruik UNION ALL
, niet of u zou ten onrechte dubbele vermeldingen verwijderen. (Er is niets om te zeggen dat het spoor niet heen en weer kan schakelen tussen dezelfde e-mails.)UNION
De Postgres-implementatie voor UNION ALL
retourneert waarden in de reeks als toegevoegd - zolang u niet . doet voeg ORDER BY
toe aan het einde of doe iets anders met het resultaat.
Houd er echter rekening mee dat elke SELECT
retourneert rijen in willekeurige volgorde tenzij ORDER BY
wordt bijgevoegd. Er is geen natuurlijke volgorde in tabellen.
Hetzelfde is niet waar voor UNION
, die alle rijen moet verwerken om mogelijke duplicaten te verwijderen. Er zijn verschillende manieren om duplicaten te bepalen, de resulterende volgorde van rijen hangt af van het gekozen algoritme en is implementatie-afhankelijk en volledig onbetrouwbaar - tenzij, nogmaals, ORDER BY
is toegevoegd.
Dus gebruik in plaats daarvan:
SELECT * FROM iter1
UNION ALL -- union all!
SELECT * FROM iter2;
Om een betrouwbare sorteervolgorde te krijgen en "het groeirecord te simuleren", kunt u niveaus als volgt volgen:
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
Oude sqlfiddle
Terzijde:als old_email
is niet gedefinieerd UNIQUE
op de een of andere manier kun je meerdere paden krijgen. U hebt een unieke kolom (of combinatie van kolommen) nodig om deze eenduidig te houden. Als al het andere faalt, kun je de interne tuple-ID ctid
. (ab-)gebruiken om sporen uit elkaar te houden. Maar je moet liever je eigen kolommen gebruiken. (Voorbeeld toegevoegd in de viool.)
Overweeg: