É assim que eu faria com uma analítica:
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
Atualização (alguma explicação):
As funções analíticas operam como uma etapa de pós-processamento. O resultado da consulta é dividido em agrupamentos (
partition by
) e a função analítica é aplicada no contexto de um agrupamento. Neste caso, a consulta é uma seleção de
p
. A função analítica que está sendo aplicada é LAG
. Como não há partition by
cláusula, há apenas um agrupamento:todo o conjunto de resultados. Este agrupamento é ordenado por id
. LAG
retorna o valor da linha anterior no agrupamento usando a ordem especificada. O resultado é que cada linha tem uma coluna adicional (aliased prev_val) que é o val
da linha anterior. Essa é a subconsulta. Em seguida, procuramos as linhas em que o
val
não corresponde ao val
da linha anterior (prev_val). O COALESCE
trata o caso especial da primeira linha que não possui um valor anterior. As funções analíticas podem parecer um pouco estranhas no começo, mas uma pesquisa sobre funções analíticas encontra muitos exemplos mostrando como elas funcionam. Por exemplo:http ://www.cs.utexas.edu/~cannata/dbms/Analytic%20Functions%20in%20Oracle%208i%20and%209i.htm Apenas lembre-se de que é uma etapa de pós-processamento. Você não poderá realizar filtragem, etc., no valor de uma função analítica, a menos que a faça uma subconsulta.