Truy vấn này sẽ mang lại số lượng cho mỗi hàng:
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;
Sau đó, bạn có thể lọc trên đó để tìm số lượng cho một hàng nhất định:
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';
Giải thích:
Bảng dẫn xuất được sử dụng để tính toán các "phân vùng" part
khác nhau cho mỗi ngày và phân bổ:
SELECT allocation, d,
d - row_number() OVER (PARTITION BY allocation ORDER BY d) AS part
FROM t
Kết quả là:
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
Ngày cụ thể được tạo bởi part
không liên quan. Đó chỉ là một số ngày sẽ giống nhau cho mỗi "nhóm" ngày trong phân bổ. Sau đó, bạn có thể đếm số lượng các giá trị giống hệt nhau của (allocation, part)
sử dụng count(*) over(...)
chức năng cửa sổ:
SELECT allocation, d, count(*) OVER (PARTITION BY allocation, part ORDER BY d) AS c
FROM (...)
ORDER BY d;
để tạo ra kết quả mong muốn của bạn.
Dữ liệu
Tôi đã sử dụng bảng sau cho ví dụ:
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
);