SQL> drop table t purge;
Table dropped.
SQL>
SQL> create table t ( id int, d_from date, d_to date );
Table created.
SQL>
SQL> insert into t
2 select rownum,
3 sysdate-dbms_random.value(1,10),
4 sysdate+dbms_random.value(1,10)
5 from dual
6 connect by level <= 10;
10 rows created.
SQL>
SQL> commit;
Commit complete.
SQL>
SQL> select * from t;
ID D_FROM D_TO
---- ------------------- -------------------
1 07/05/2016 08:28:14 14/05/2016 17:45:52
2 02/05/2016 17:57:51 17/05/2016 15:57:40
3 06/05/2016 19:28:18 18/05/2016 00:47:37
4 02/05/2016 00:51:46 20/05/2016 04:30:59
5 07/05/2016 19:39:47 21/05/2016 09:01:55
6 06/05/2016 16:11:18 16/05/2016 21:16:21
7 07/05/2016 17:40:10 21/05/2016 08:15:55
8 05/05/2016 13:55:21 18/05/2016 20:55:35
9 09/05/2016 04:46:35 14/05/2016 22:33:12
10 04/05/2016 06:45:30 18/05/2016 22:55:01
10 rows selected.
SQL>
SQL> with all_days as
2 ( select id, d_from, d_to, trunc(d_from) + column_value - 1 dy
3 from t,
4 table(cast(multiset(
5 select rownum r
6 from dual
7 connect by level <= trunc(t.d_to) - trunc(t.d_from) + 1
8 ) as sys.odcinumberlist ))
9 ),
10 time_per_day as
11 ( select
12 id,
13 case
14 when dy < d_from then d_from - dy -- partial first day
15 when trunc(d_to)=dy then d_to - dy -- partial last day
16 else 1
17 end time_elapsed,
18 case when to_char(dy,'DY') in ('SAT','SUN') then 'Weekend' else 'Weekday' end tag
19 from all_days
20 )
21 select id,
22 tag,
23 sum(time_elapsed) days
24 from time_per_day
25 group by id,tag;
ID TAG DAYS
---- ------- ----------
3 Weekday 7.84438657
5 Weekday 10
8 Weekday 9.45203704
9 Weekday 4.1990162
1 Weekday 5
10 Weekday 10.2364699
6 Weekend 4
7 Weekday 10
4 Weekday 13.2241319
5 Weekend 4.195625
2 Weekday 11.4135532
2 Weekend 4
4 Weekend 4
6 Weekday 6.56086806
8 Weekend 4
1 Weekend 2.093125
7 Weekend 4.08061343
10 Weekend 4
3 Weekend 4
9 Weekend .939722222
20 rows selected.
SQL>
SQL>