To zapytanie zwróci liczbę dla każdego wiersza:
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;
Następnie możesz go filtrować, aby znaleźć liczby dla danego wiersza:
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';
Wyjaśnienie:
Tabela pochodna służy do obliczania różnych "partycji" part
dla każdej daty i przydziału:
SELECT allocation, d,
d - row_number() OVER (PARTITION BY allocation ORDER BY d) AS part
FROM t
Wynik:
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
Konkretna data wygenerowana przez part
nie ma znaczenia. To tylko pewna data, która będzie taka sama dla każdej „grupy” dat w ramach alokacji. Następnie możesz policzyć liczbę identycznych wartości (allocation, part)
używając count(*) over(...)
funkcja okna:
SELECT allocation, d, count(*) OVER (PARTITION BY allocation, part ORDER BY d) AS c
FROM (...)
ORDER BY d;
aby uzyskać pożądany rezultat.
Dane
Jako przykład użyłem poniższej tabeli:
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
);