Điều này là khá phức tạp. Đây là một cách tiếp cận bằng cách sử dụng các hàm cửa sổ.
Đầu tiên, hãy sử dụng bảng ngày để liệt kê những ngày không có ngày nghỉ cuối tuần (bạn cũng có thể tính ngày nghỉ nếu muốn). Sau đó, mở rộng các khoảng thời gian thành một ngày trên mỗi hàng, bằng cách sử dụng dấu chấm không tương đương.
Sau đó, bạn có thể sử dụng một thủ thuật để xác định các ngày tuần tự. Thủ thuật này là tạo một số tuần tự cho mỗi id và trừ nó khỏi số thứ tự cho các ngày. Đây là một hằng số cho các ngày liên tiếp. Bước cuối cùng chỉ đơn giản là tổng hợp.
Truy vấn kết quả giống như sau:
with d as (
select d.*, row_number() over (order by date) as seqnum
from dates d
where day not in ('Saturday', 'Sunday')
)
select t.id, min(t.date) as startdate, max(t.date) as enddate, sum(duration)
from (select t.*, ds.seqnum, ds.date,
(d.seqnum - row_number() over (partition by id order by ds.date) ) as grp
from table t join
d ds
on ds.date between t.startdate and t.enddate
) t
group by t.id, grp;
CHỈNH SỬA:
Sau đây là phiên bản trên cái này SQL Fiddle:
with d as (
select d.*, row_number() over (order by date) as seqnum
from datetable d
where day not in ('Saturday', 'Sunday')
)
select t.id, min(t.date) as startdate, max(t.date) as enddate, sum(duration)
from (select t.*, ds.seqnum, ds.date,
(ds.seqnum - row_number() over (partition by id order by ds.date) ) as grp
from (select t.*, 'abc' as id from table1 t) t join
d ds
on ds.dateid between t.startdate and t.enddate
) t
group by grp;
Tôi tin rằng điều này đang hoạt động, nhưng bảng ngày tháng không có tất cả các ngày trong đó.