Esta consulta produzirá as contagens para cada linha:
SELECT allocation, d, count(*) OVER (PARTITION BY allocation, part ORDER BY d) AS c
FROM (
SELECT allocation, d,
d - row_number() OVER (PARTITION BY allocation ORDER BY d) AS part
FROM t
)
ORDER BY d;
Você pode então filtrá-lo para encontrar as contagens de uma determinada linha:
SELECT c
FROM (
SELECT allocation, d, count(*) OVER (PARTITION BY allocation, part ORDER BY d) AS c
FROM (
SELECT allocation, d,
d - row_number() OVER (PARTITION BY allocation ORDER BY d) AS part
FROM t
)
)
WHERE d = DATE '2015-01-05';
Explicação:
A tabela derivada é usada para calcular diferentes "partições"
part
para cada data e alocação: SELECT allocation, d,
d - row_number() OVER (PARTITION BY allocation ORDER BY d) AS part
FROM t
O resultado é:
allocation d part
--------------------------------
Same 01.01.15 31.12.14
Good 02.01.15 01.01.15
Same 03.01.15 01.01.15
Same 04.01.15 01.01.15
Same 05.01.15 01.01.15
Good 06.01.15 04.01.15
A data concreta produzida por
part
é irrelevante. É apenas uma data que será a mesma para cada "grupo" de datas dentro de uma alocação. Você pode então contar o número de valores idênticos de (allocation, part)
usando o count(*) over(...)
função da janela:SELECT allocation, d, count(*) OVER (PARTITION BY allocation, part ORDER BY d) AS c
FROM (...)
ORDER BY d;
para produzir o resultado desejado.
Dados
Eu usei a seguinte tabela para o exemplo:
CREATE TABLE t AS (
SELECT DATE '2015-01-01' AS d, 'Same' AS allocation FROM dual UNION ALL
SELECT DATE '2015-01-02' AS d, 'Good' AS allocation FROM dual UNION ALL
SELECT DATE '2015-01-03' AS d, 'Same' AS allocation FROM dual UNION ALL
SELECT DATE '2015-01-04' AS d, 'Same' AS allocation FROM dual UNION ALL
SELECT DATE '2015-01-05' AS d, 'Same' AS allocation FROM dual UNION ALL
SELECT DATE '2015-01-06' AS d, 'Good' AS allocation FROM dual
);