di 10g/11g Anda dapat menggunakan klausa model untuk ini.
SQL> with emps as (select rownum id, name, start_date,
2 end_date, trunc(end_date)-trunc(start_date) date_range
3 from table1)
4 select name, the_date
5 from emps
6 model partition by(id as key)
7 dimension by(0 as f)
8 measures(name, start_date, cast(null as date) the_date, date_range)
9 rules (the_date [for f from 0 to date_range[0] increment 1] = start_date[0] + cv(f),
10 name[any] = name[0]);
NAME THE_DATE
----------- ----------
DAVID SMITH 01-01-2001
DAVID SMITH 01-02-2001
DAVID SMITH 01-03-2001
DAVID SMITH 01-04-2001
DAVID SMITH 01-05-2001
DAVID SMITH 01-06-2001
JOHN SMITH 02-07-2012
JOHN SMITH 02-08-2012
JOHN SMITH 02-09-2012
9 rows selected.
yaitu kueri dasar Anda:
select rownum id, name, start_date,
end_date, trunc(end_date)-trunc(start_date) date_range
from table1
cukup tentukan tanggal + rentangnya (saya menggunakan id rownum, tetapi jika Anda memiliki PK, Anda dapat menggunakannya sebagai gantinya.
partisi membagi perhitungan kita per ID(baris unik):
6 model partition by(id as key)
langkah-langkahnya:
8 measures(name, start_date, cast(null as date) the_date, date_range)
mendefinisikan atribut yang akan kita hasilkan/hitung. dalam hal ini, kami bekerja dengan nama, dan tanggal_mulai ditambah rentang baris yang akan dihasilkan. selain itu saya telah menetapkan kolom the_date
yang akan menampung tanggal yang dihitung (yaitu kami ingin menghitung tanggal_mulai + n di mana n adalah dari 0 hingga rentang.
aturan menentukan BAGAIMANA kita akan mengisi kolom kita:
9 rules (the_date [for f from 0 to date_range[0] increment 1] = start_date[0] + cv(f),
10 name[any] = name[0]);
begitu juga dengan
the_date [for f from 0 to date_range[0] increment 1]
kami mengatakan bahwa kami akan menghasilkan jumlah baris yang memiliki rentang_tanggal+1 (yaitu total 6 tanggal). nilai f
dapat dirujuk melalui cv
(nilai saat ini) fungsi.
jadi pada baris 1 untuk david, kita akan memiliki the_date [0] = start_date+0
dan selanjutnya pada baris 2, kita akan memiliki the_date [1] = start_date+1
. sepanjang jalan hingga start_date+5 (yaitu end_date
)
p.s.untuk terhubung dengan Anda harus melakukan sesuatu seperti ini:
select
A.EMPLOYEE_NAME,
A.START_DATE+(b.r-1) AS INDIVIDUAL_DAY,
TO_CHAR(A.START_DATE,'MM/DD/YYYY') START_DATE,
TO_CHAR(A.END_DATE,'MM/DD/YYYY') END_DATE
FROM table1 A
cross join (select rownum r
from (select max(end_date-start_date) d from table1)
connect by level-1 <= d) b
where A.START_DATE+(b.r-1) <= A.END_DATE
order by 1, 2;
yaitu mengisolasi koneksi dengan subkueri, lalu memfilter baris di mana hari_individu> tanggal_akhir.
tetapi saya TIDAK AKAN merekomendasikan pendekatan ini. kinerjanya akan lebih buruk dibandingkan dengan pendekatan model (terutama jika rentangnya besar).