2016-12-01 6 views
7

मैं एक प्रकार MyType इस प्रकार परिभाषित किया गया है:Oracle SQL: उपयोगकर्ता परिभाषित प्रकार रिटर्न के साथ अंतराल समारोह का उपयोग कर "असंगत डेटाटाइप्स"

create or replace type MyType as varray(20000) of number(18); 

और एक मेज MyTable के रूप में परिभाषित इस प्रकार है:

create table MyTable (
    id  number(18) primary key 
    ,widgets MyType 
) 

मैं निम्नलिखित एसक्यूएल का उपयोग कर MyTable में प्रत्येक पंक्ति के लिए विजेट और इसकी तार्किक पिछली पंक्ति का चयन करने के कोशिश कर रहा हूँ:

select t.id 
     ,lag(t.widgets,1) over (order by t.id) as widgets_previous 
from MyTable t 
order by t.id; 
ORA-00932: inconsistent datatypes: expected - got MYSCHEMA.MYTYPE 

अगर मैं MyType के बजाय ठीक उसी क्वेरी प्रकार varchar या संख्या का एक स्तंभ का उपयोग चलाने यह ठीक काम करता है:और मैं प्रतिक्रिया मिल।

वर्तमान पंक्ति में स्तंभ और इसकी पिछली पंक्ति के प्रकार के समान होना चाहिए तो मैं केवल यह उपयोगकर्ता परिभाषित प्रकार से संबंधित कुछ है मान सकते हैं।

मैं कुछ खास एक उपयोगकर्ता परिभाषित प्रकार के साथ अंतराल उपयोग करने के लिए क्या करने की जरूरत है, या अंतराल उपयोगकर्ता परिभाषित प्रकार का समर्थन नहीं करता? यदि उत्तरार्द्ध, क्या कोई अन्य उपयोगिता कार्य है जो समान कार्यक्षमता प्रदान करेगा या क्या मुझे इसे प्राप्त करने के लिए पारंपरिक स्वयं को शामिल करने की आवश्यकता है?

+0

मैं इस अपने आप को अभी परीक्षण नहीं कर सकते, दुर्भाग्य से, लेकिन क्या होता है अगर आप कार्य करें: 'अंतराल (t.widgets, 1, डाली (MyType के रूप में नल)) ओवर (टी.आईडी द्वारा आदेश) '? – Boneist

+0

@ बोनिस्ट - मुझे डर है कि मुझे अभी भी ओआरए -00 9 32-थैंक्स मिलते हैं, एक अच्छा विचार! – Pancho

+0

नेस्टेड टेबल का उपयोग करने का एक विकल्प स्पष्ट रूप से एक टेबल बनाना होगा और उसमें अपना डेटा स्टोर करना होगा, और उसके बाद नई तालिका से एक फ़िकी को mytable पर वापस लेना होगा (और फिर डेटासेट की तुलना करने के लिए SQL का उपयोग करें)। अन्यथा, यह स्वयं शामिल करने का सबसे आसान तरीका है (यानी पिछली पंक्ति की आईडी पाएं और वर्तमान आईडी में शामिल हों) – Boneist

उत्तर

2

सब से ऊपर मैं मैं क्या जरूरत को प्राप्त करने के लिए सबसे प्रभावी तरीके के रूप में निम्नलिखित के लिए चुना गया है पढ़ने के बाद:

select curr.id 
     ,curr.widgets as widgets 
     ,prev.widgets as previous_widgets 
from (select a.id          
      ,a.widgets 
      ,lag(a.id,1) over (order by a.id) as previous_id 
     from mytable a 
    ) curr 
    left join mytable prev on (prev.id = curr.previous_id) 
order by curr.id 

अर्थात्। एक अंतराल में एक अंतराल का उपयोग करके एक अंतराल/स्वयं हाइब्रिड में शामिल हो जाता है कि यह शामिल स्थिति की पहचान करने के बारे में शिकायत नहीं करता है। यह काफी साफ है जो मुझे लगता है और मुझे वांछित के रूप में मेरे संग्रह मिलते हैं। बेहद उपयोगी इनपुट के लिए सभी को धन्यवाद।

1

आप यूडीटी के साथ lag का उपयोग कर सकते हैं। समस्या varray

क्या यह आपको परिणाम देता है?

select t.id 
     ,lag(
       (select listagg(column_value, ',') within group (order by column_value) 
        from table(t.widgets)) 
      ,1) over (order by t.id) as widgets_previous 
from MyTable t 
order by t.id; 
+0

हाय @ कैस्पर दुख की बात है कि मेरी समस्या एक संयुक्त है: भाग 1: मैं नेस्टेड का उपयोग करने में असमर्थ हूं varrays पर टेबल (भले ही मैं वास्तव में करना चाहूंगा) क्योंकि 12c ओरेकल पर अस्थायी तालिकाओं (ओआरए -14457) में कॉलम के रूप में नेस्टेड टेबल का समर्थन नहीं करना प्रतीत होता है। भाग 2: मैं listagg से परिचित हूं और एक अलग उपयोग के मामले में यह काम कर सकता है हालांकि मैं संग्रह के बाद हूं इसलिए मैं विभिन्न तुलना करने के लिए ओरेकल "मल्टीसेट" ऑपरेटरों का उपयोग कर सकता हूं। - आपके सहयोग के लिए बहुत धन्यवाद! – Pancho

+1

'टीटीआईडी ​​का चयन करें, टी 2.विड्जेट्स माईटेबल टी से बाहर निकलें बाहरी में MyTable t2 (t.id = t2.id + 1) में शामिल हों;' क्या यह आपकी समस्या का समाधान नहीं करेगा? – Kacper

+0

हाय @ कैस्पर यह दृष्टिकोण अवधारणात्मक रूप से समान है जो मैंने नीचे दिया है, हालांकि यह लगातार आईडी मानों पर निर्भर करता है जिसे मेरे परिदृश्य में गारंटी नहीं दी जा सकती है :) – Pancho

0

आप की तरह कुछ की कोशिश कर सकते:

SQL> create or replace type TestType as varray(20000) of number(18); 
Type created. 
SQL> create table TestTable (
    id  number(18) primary key 
    ,widgets TestType 
) 
Table created. 
SQL> delete from testtable 
0 rows deleted. 
SQL> insert into TestTable values (1, TestType(1,2,3,4)) 
1 row created. 
SQL> insert into TestTable values (2, TestType(5,6,7)) 
1 row created. 
SQL> insert into TestTable values (3, TestType()) 
1 row created. 
SQL> insert into TestTable values (4,null) 
1 row created. 
SQL> commit 
Commit complete. 

SQL> -- show all data with widgets 
SQL> select t.id, w.column_value as widget_ids 
from testtable t, table(t.widgets) w 

     ID WIDGET_IDS 
---------- ---------- 
     1   1 
     1   2 
     1   3 
     1   4 
     2   5 
     2   6 
     2   7 

7 rows selected. 
SQL> -- show with lag function 
SQL> select t.id, lag(w.column_value, 1) over (order by t.id) as widgets_previous 
from testtable t, table(t.widgets) w 

     ID WIDGETS_PREVIOUS 
---------- ---------------- 
     1     
     1    1 
     1    2 
     1    3 
     2    4 
     2    5 
     2    6 

7 rows selected. 
+0

hi @tbone - जो आप लौट रहे हैं वह काफी नहीं है जो मैं हूं बाद। आपने 4 पंक्तियां डाली हैं, इसलिए चयन को उसी पंक्ति को वापस करना चाहिए, पंक्ति 1 होल्डिंग पंक्ति 1 का संग्रह और पिछले संग्रह के लिए शून्य, पंक्ति 2 होल्डिंग पंक्ति 2 का संग्रह और पंक्ति 1 का संग्रह और इसी तरह ... इनपुट के लिए धन्यवाद! – Pancho

+0

आह, ठीक है, मैंने जो समझा था उसे गलत समझा। जैसा कि आपने सुझाव दिया है कि तालिका में शामिल होना आपके जैसा तरीका है। – tbone

संबंधित मुद्दे