trong 10g / 11g, bạn có thể sử dụng mệnh đề mô hình cho việc này.
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.
tức là truy vấn cơ sở của bạn:
select rownum id, name, start_date,
end_date, trunc(end_date)-trunc(start_date) date_range
from table1
chỉ cần xác định ngày + phạm vi (Tôi đã sử dụng id rownum, nhưng nếu bạn có PK, bạn có thể sử dụng nó để thay thế.
phân vùng phân chia các phép tính của chúng tôi cho mỗi ID (hàng duy nhất):
6 model partition by(id as key)
các biện pháp:
8 measures(name, start_date, cast(null as date) the_date, date_range)
xác định các thuộc tính mà chúng ta sẽ xuất / tính toán. trong trường hợp này, chúng tôi đang làm việc với tên và ngày bắt đầu cộng với phạm vi hàng cần tạo. ngoài ra, tôi đã xác định một cột the_date
điều đó sẽ giữ ngày được tính toán (tức là chúng tôi muốn tính toán start_date + n trong đó n là từ 0 đến phạm vi.
các quy tắc xác định CÁCH chúng ta sẽ điền các cột của mình:
9 rules (the_date [for f from 0 to date_range[0] increment 1] = start_date[0] + cv(f),
10 name[any] = name[0]);
vậy với
the_date [for f from 0 to date_range[0] increment 1]
chúng tôi đang nói rằng chúng tôi sẽ tạo ra số hàng mà date_range giữ + 1 (tức là tổng cộng 6 ngày). giá trị của f
có thể được tham chiếu thông qua cv
(giá trị hiện tại).
vì vậy trên hàng 1 cho david, chúng ta sẽ có the_date [0] = start_date+0
và sau đó ở hàng 2, chúng ta sẽ có the_date [1] = start_date+1
. tất cả các cách tính đến start_date + 5 (tức là end_date
)
p.s.for kết nối bằng cách bạn cần làm điều gì đó như sau:
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;
tức là cô lập kết nối bằng một truy vấn con, sau đó lọc ra các hàng có cá nhân_ngày> ngày.
nhưng tôi KHÔNG NÊN giới thiệu cách tiếp cận này. hiệu suất của nó sẽ kém hơn so với cách tiếp cận mô hình (đặc biệt nếu phạm vi trở nên lớn hơn).