PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

L'ordine è conservato dopo UNION in PostgreSQL?

Fondamentalmente, la tua domanda non è corretta per cominciare. Usa UNION ALL , non UNION o rimuoveresti erroneamente le voci duplicate. (Non c'è nulla da dire che il percorso non può passare avanti e indietro tra le stesse email.)

L'implementazione di Postgres per UNION ALL restituisce i valori nella sequenza come aggiunto, purché non aggiungi ORDER BY alla fine o fare qualsiasi altra cosa con il risultato.
Attenzione però, che ogni SELECT restituisce le righe in ordine arbitrario a meno che ORDER BY è allegato. Non c'è un ordine naturale nelle tabelle.

Lo stesso non true per UNION , che deve elaborare tutte le righe per rimuovere possibili duplicati. Esistono vari modi per determinare i duplicati, l'ordine delle righe risultante dipende dall'algoritmo scelto ed è dipendente dall'implementazione e completamente inaffidabile, a meno che, ancora una volta, ORDER BY viene aggiunto.

Quindi usa invece:

SELECT * FROM iter1
UNION ALL  -- union all!
SELECT * FROM iter2;

Per ottenere un ordinamento affidabile e "simulare il record di crescita", puoi tenere traccia dei livelli come questo:

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<>violino qui
Vecchio sqlfiddle

A parte:se old_email non è definito UNIQUE in qualche modo, puoi ottenere più percorsi. Avresti bisogno di una colonna univoca (o combinazione di colonne) per mantenerla univoca. Se tutto il resto fallisce, puoi (ab-)usare l'ID tupla interno ctid allo scopo di distinguere le tracce. Ma dovresti piuttosto usare le tue colonne. (Aggiunto esempio nel violino.)

Considera: