Você pode usar o
COUNT( DISTINCT code ) OVER ( PARTITION BY id )
função analítica para obter sua resposta usando apenas uma varredura de tabela:SQL Fiddle
Configuração do esquema Oracle 11g R2 :
CREATE TABLE table_name ( ID, Code, "DATE" ) AS
SELECT 1, 'A', DATE '2018-02-19' FROM DUAL UNION ALL
SELECT 1, 'B', DATE '2018-02-18' FROM DUAL UNION ALL
SELECT 1, 'B', DATE '2018-02-17' FROM DUAL UNION ALL
SELECT 1, 'B', DATE '2018-02-16' FROM DUAL UNION ALL
SELECT 2, 'A', DATE '2018-02-17' FROM DUAL UNION ALL
SELECT 2, 'B', DATE '2018-02-16' FROM DUAL UNION ALL
SELECT 3, 'A', DATE '2018-02-17' FROM DUAL UNION ALL
SELECT 3, 'A', DATE '2018-02-16' FROM DUAL UNION ALL
SELECT 4, 'D', DATE '2018-02-16' FROM DUAL;
Consulta 1 :
SELECT ID,
Code,
"DATE"
FROM (
SELECT t.*,
COUNT( DISTINCT code ) OVER ( PARTITION BY id ) AS num_changes
FROM table_name t
WHERE "DATE" BETWEEN DATE '2018-02-16'
AND DATE '2018-02-19'
)
WHERE num_changes > 1
Resultados :
| ID | CODE | DATE |
|----|------|----------------------|
| 1 | A | 2018-02-19T00:00:00Z |
| 1 | B | 2018-02-18T00:00:00Z |
| 1 | B | 2018-02-17T00:00:00Z |
| 1 | B | 2018-02-16T00:00:00Z |
| 2 | A | 2018-02-17T00:00:00Z |
| 2 | B | 2018-02-16T00:00:00Z |
Consulta 2 :
SELECT ID,
Code,
"DATE"
FROM (
SELECT t.*,
COUNT( DISTINCT code ) OVER ( PARTITION BY id ) AS num_changes
FROM table_name t
WHERE "DATE" BETWEEN DATE '2018-02-16'
AND DATE '2018-02-18'
)
WHERE num_changes > 1
Resultados :
| ID | CODE | DATE |
|----|------|----------------------|
| 2 | A | 2018-02-17T00:00:00Z |
| 2 | B | 2018-02-16T00:00:00Z |