Pada dasarnya, permintaan Anda salah untuk memulai. Gunakan UNION ALL
, bukan atau Anda akan salah menghapus entri duplikat. (Tidak ada yang mengatakan bahwa jejak tidak dapat beralih antara email yang sama.)UNION
Implementasi Postgres untuk UNION ALL
mengembalikan nilai dalam urutan seperti yang ditambahkan - selama Anda tidak tambahkan ORDER BY
di akhir atau lakukan hal lain dengan hasilnya.
Namun perlu diketahui, bahwa setiap SELECT
mengembalikan baris dalam urutan sewenang-wenang kecuali ORDER BY
ditambahkan. Tidak ada urutan alami dalam tabel.
Hal yang sama tidak benar untuk UNION
, yang harus memproses semua baris untuk menghapus kemungkinan duplikat. Ada berbagai cara untuk menentukan duplikat, urutan baris yang dihasilkan bergantung pada algoritme yang dipilih dan bergantung pada implementasi dan sama sekali tidak dapat diandalkan - kecuali, sekali lagi, ORDER BY
ditambahkan.
Jadi gunakan sebagai gantinya:
SELECT * FROM iter1
UNION ALL -- union all!
SELECT * FROM iter2;
Untuk mendapatkan urutan penyortiran yang andal, dan "mensimulasikan catatan pertumbuhan", Anda dapat melacak level seperti ini:
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 di sini
Lama sqlfiddle
Selain:jika old_email
tidak didefinisikan UNIQUE
dalam beberapa cara, Anda bisa mendapatkan banyak jalur. Anda memerlukan kolom unik (atau kombinasi kolom) agar tidak ambigu. Jika semuanya gagal, Anda dapat (ab-)menggunakan ID tuple internal ctid
untuk tujuan membedakan jejak. Tetapi Anda sebaiknya menggunakan kolom Anda sendiri. (Menambahkan contoh di biola.)
Pertimbangkan: