Ecco come lo farei con un'analitica:
SELECT id, val
FROM ( SELECT id, val
,LAG(val) OVER (ORDER BY id) AS prev_val
FROM p ) x
WHERE val <> COALESCE(prev_val, val)
ORDER BY id
Aggiornamento (qualche spiegazione):
Le funzioni analitiche operano come una fase di post-elaborazione. Il risultato della query è suddiviso in raggruppamenti (partition by
) e la funzione analitica viene applicata nel contesto di un raggruppamento.
In questo caso, la query è una selezione da p
. La funzione analitica applicata è LAG
. Poiché non esiste una partition by
clausola, esiste un solo raggruppamento:l'intero set di risultati. Questo raggruppamento è ordinato per id
. LAG
restituisce il valore della riga precedente nel raggruppamento utilizzando l'ordine specificato. Il risultato è che ogni riga ha una colonna aggiuntiva (alias prev_val) che è il val
della riga precedente. Questa è la sottoquery.
Quindi cerchiamo le righe in cui è val
non corrisponde al val
della riga precedente (prev_val). Il COALESCE
gestisce il caso speciale della prima riga che non ha un valore precedente.
Le funzioni analitiche possono sembrare un po' strane all'inizio, ma una ricerca sulle funzioni analitiche trova molti esempi che illustrano come funzionano. Ad esempio:http ://www.cs.utexas.edu/~cannata/dbms/Analytic%20Functions%20in%20Oracle%208i%20and%209i.htm Ricorda solo che è una fase di post-elaborazione. Non sarai in grado di eseguire filtri, ecc. sul valore di una funzione analitica a meno che non la sottointerroghi.