По принцип вашето запитване е неправилно като начало. Използвайте UNION ALL
, а не или бихте премахнали неправилно дублиращи се записи. (Няма нищо, което да казва, че пътеката не може да превключва напред и назад между едни и същи имейли.)UNION
Реализацията на Postgres за UNION ALL
връща стойности в добавената последователност - стига да не добавете ORDER BY
накрая или направете нещо друго с резултата.
Имайте предвид обаче, че всеки SELECT
връща редове в произволен ред, освен ако ORDER BY
се добавя. Няма естествен ред в таблиците.
Същото ене вярно за UNION
, който трябва да обработи всички редове, за да премахне възможни дубликати. Има различни начини за определяне на дубликати, резултантният ред на редовете зависи от избрания алгоритъм и зависи от изпълнението и е напълно ненадежден - освен ако отново ORDER BY
се добавя.
Затова използвайте вместо това:
SELECT * FROM iter1
UNION ALL -- union all!
SELECT * FROM iter2;
За да получите надежден ред на сортиране и да „симулирате запис на растеж“, можете да проследявате нива като това:
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;
Настрана:ако old_email
не е дефиниран UNIQUE
по някакъв начин можете да получите множество следи. Ще ви трябва уникална колона (или комбинация от колони), за да го поддържате недвусмислен. Ако всичко останало се провали, можете (зло) да използвате вътрешния ID на кортежа ctid
с цел разграничаване на пътеките. Но по-скоро трябва да използвате свои собствени колони. (Добавен пример във цигулката.)
Помислете за следното: