Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

कुंजी द्वारा दिनांक सीमा के लिए पंक्तियाँ कैसे उत्पन्न करें

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;

यानी कनेक्ट को एक सबक्वेरी से अलग करें, फिर उन पंक्तियों को फ़िल्टर करें जहां व्यक्तिगत_दिन> समाप्ति तिथि।

लेकिन मैं इस दृष्टिकोण की सिफारिश नहीं करूंगा। इसका प्रदर्शन मॉडल दृष्टिकोण की तुलना में खराब होगा (खासकर यदि श्रेणियां बड़ी हो जाती हैं)।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL क्वेरी, औसत चढ़ाई और जोड़ी जो सबसे अधिक चोटियों पर चढ़ी है

  2. क्लॉज द्वारा ऑर्डर के साथ संयोजन में ओरेकल एसक्यूएल स्टेटमेंट में राउनम का उपयोग करना

  3. किसी भी प्रत्यक्ष कार्य (ओरेकल) का उपयोग किए बिना शब्दों में संख्या प्रदर्शित करने के लिए SQL कथन

  4. रेगेक्सपी में (*) और .* में क्या अंतर है?

  5. DUAL . से सबक्वायरी के लिए काम नहीं कर रहा Oracle आदेश