Điều này hơi phức tạp. Thay vì sử dụng rank()
hoặc tương tự, sử dụng lag()
để xem khi có điều gì đó thay đổi. Sau đó tính tổng tích lũy của cờ.
select dept, date1,
CASE WHEN StartFlag = 0 THEN 1
ELSE 1+StartFlag+NVL(lag(StartFlag) over (order by date1),0)
END as rnk
from (select t1.*,
(case when dept = lag(dept) over (order by date1)
then 1
else 0
end) as StartFlag
from t1
) t1
order by date1;
Đây là SQLFiddle.
CHỈNH SỬA:
Đây là Gordon đang chỉnh sửa câu trả lời của riêng tôi. Giáo sư. Truy vấn ban đầu là 90% chặng đường đến đó. Nó đã xác định các nhóm nơi các con số sẽ tăng lên, nhưng không chỉ định các con số trong các nhóm. Tôi sẽ làm điều này với một cấp độ khác của row_number()
như trong:
select dept, date1,
row_number() over (partition by dept, grp order by date1) as rnk
from (select dept, date1, startflag,
sum(StartFlag) over (partition by dept order by date1) as grp
from (select t1.*,
(case when dept = lag(dept) over (order by date1)
then 0
else 1
end) as StartFlag
from t1
) t1
) t1
order by date1;
Vì vậy, ý tưởng tổng thể là như sau. Lần đầu tiên sử dụng lag()
để xác định nơi bắt đầu của một nhóm (nghĩa là nơi có sự thay đổi của bộ phận từ ngày này sang ngày tiếp theo). Sau đó, gán một "id nhóm" cho những thứ này, bằng cách tính tổng tích lũy. Đây là những bản ghi sẽ được liệt kê. Bước cuối cùng là liệt kê chúng bằng cách sử dụng row_number()
.