10g/11g में आप इसके लिए मॉडल क्लॉज का उपयोग कर सकते हैं।
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.
यानी आपकी मूल क्वेरी:
select rownum id, name, start_date,
end_date, trunc(end_date)-trunc(start_date) date_range
from table1
बस दिनांक + सीमा को परिभाषित करता है (मैंने राउनम आईडी का उपयोग किया है, लेकिन यदि आपके पास पीके है तो आप इसके बजाय इसका उपयोग कर सकते हैं।
विभाजन हमारी गणना को प्रति आईडी (अद्वितीय पंक्ति) में विभाजित करता है:
6 model partition by(id as key)
उपाय:
8 measures(name, start_date, cast(null as date) the_date, date_range)
उन विशेषताओं को परिभाषित करता है जिन्हें हम आउटपुट/गणना करेंगे। इस मामले में, हम नाम के साथ काम कर रहे हैं, और start_date प्लस पंक्तियों की श्रेणी उत्पन्न करने के लिए। इसके अतिरिक्त मैंने एक कॉलम the_date
. परिभाषित किया है जो परिकलित तिथि को धारण करेगा (अर्थात हम start_date + n को कैलकुलेट करना चाहते हैं, जहां n 0 से सीमा तक है।
नियम परिभाषित करते हैं कि हम अपने कॉलम को कैसे पॉप्युलेट करने जा रहे हैं:
9 rules (the_date [for f from 0 to date_range[0] increment 1] = start_date[0] + cv(f),
10 name[any] = name[0]);
तो
. के साथthe_date [for f from 0 to date_range[0] increment 1]
हम कह रहे हैं कि हम उन पंक्तियों की संख्या उत्पन्न करेंगे जो date_range +1 रखती हैं (यानी कुल 6 तिथियां)। f
. का मान cv
. के माध्यम से संदर्भित किया जा सकता है (वर्तमान मान) फ़ंक्शन।
तो डेविड के लिए पंक्ति 1 पर, हमारे पास the_date [0] = start_date+0
होगा और बाद में पंक्ति 2 पर, हमारे पास the_date [1] = start_date+1
. होगा . start_date+5 (यानी end_date
. तक सभी तरह से )
p.s. आपके द्वारा कनेक्ट करने के लिए आपको कुछ ऐसा करना होगा:
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;
यानी कनेक्ट को एक सबक्वेरी से अलग करें, फिर उन पंक्तियों को फ़िल्टर करें जहां व्यक्तिगत_दिन> समाप्ति तिथि।
लेकिन मैं इस दृष्टिकोण की सिफारिश नहीं करूंगा। इसका प्रदर्शन मॉडल दृष्टिकोण की तुलना में खराब होगा (खासकर यदि श्रेणियां बड़ी हो जाती हैं)।