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

अल्पविराम से अलग किए गए मानों को ऑरैकल में पंक्तियों में कैसे परिवर्तित करें?

मैं मानता हूं कि यह वास्तव में खराब डिजाइन है। अगर आप उस डिजाइन को नहीं बदल सकते हैं तो इसे आजमाएं:

select distinct id, trim(regexp_substr(value,'[^,]+', 1, level) ) value, level
  from tbl1
   connect by regexp_substr(value, '[^,]+', 1, level) is not null
   order by id, level;

आउटपुट

id value level
1   AA  1
1   UT  2
1   BT  3
1   SK  4
1   SX  5
2   AA  1
2   UT  2
2   SX  3
3   UT  1
3   SK  2
3   SX  3
3   ZF  4

इसका श्रेय

डुप्लिकेट को अधिक सुरुचिपूर्ण और कुशल तरीके से निकालने के लिए (@mathguy को श्रेय)

select id, trim(regexp_substr(value,'[^,]+', 1, level) ) value, level
  from tbl1
   connect by regexp_substr(value, '[^,]+', 1, level) is not null
      and PRIOR id =  id 
      and PRIOR SYS_GUID() is not null  
   order by id, level;

यदि आप "ANSIer" दृष्टिकोण चाहते हैं तो CTE के साथ जाएं:

with t (id,res,val,lev) as (
           select id, trim(regexp_substr(value,'[^,]+', 1, 1 )) res, value as val, 1 as lev
             from tbl1
            where regexp_substr(value, '[^,]+', 1, 1) is not null
            union all           
            select id, trim(regexp_substr(val,'[^,]+', 1, lev+1) ) res, val, lev+1 as lev
              from t
              where regexp_substr(val, '[^,]+', 1, lev+1) is not null
              )
select id, res,lev
  from t
order by id, lev;

आउटपुट

id  val lev
1   AA  1
1   UT  2
1   BT  3
1   SK  4
1   SX  5
2   AA  1
2   UT  2
2   SX  3
3   UT  1
3   SK  2
3   SX  3
3   ZF  4

एमटी0 द्वारा एक और पुनरावर्ती दृष्टिकोण लेकिन रेगेक्स के बिना:

WITH t ( id, value, start_pos, end_pos ) AS
  ( SELECT id, value, 1, INSTR( value, ',' ) FROM tbl1
  UNION ALL
  SELECT id,
    value,
    end_pos                    + 1,
    INSTR( value, ',', end_pos + 1 )
  FROM t
  WHERE end_pos > 0
  )
SELECT id,
  SUBSTR( value, start_pos, DECODE( end_pos, 0, LENGTH( value ) + 1, end_pos ) - start_pos ) AS value
FROM t
ORDER BY id,
  start_pos;

मैंने 30000 पंक्तियों के डेटासेट के साथ 3 दृष्टिकोणों की कोशिश की है और 118104 पंक्तियों को लौटाया और निम्नलिखित औसत परिणाम प्राप्त किए:

  • मेरा पुनरावर्ती दृष्टिकोण:5 सेकंड
  • MT0 दृष्टिकोण:4 सेकंड
  • Mathguy दृष्टिकोण:16 सेकंड
  • MT0 पुनरावर्ती दृष्टिकोण नो-रेगेक्स:3.45 सेकंड

@Mathguy ने एक बड़े डेटासेट के साथ भी परीक्षण किया है:

<ब्लॉकक्वॉट>

सभी मामलों में रिकर्सिव क्वेरी (मैंने केवल नियमित सबस्ट्र और इंस्ट्र के साथ एक का परीक्षण किया) 2 से 5 के कारक से बेहतर करता है। यहां स्ट्रिंग्स/टोकन प्रति स्ट्रिंग के संयोजन और पदानुक्रमित बनाम रिकर्सिव, पदानुक्रमित पहले के लिए सीटीएएस निष्पादन समय हैं। . हर समय सेकंड में

  • 30,000 x 4:5 / 1.
  • 30,000 x 10:15 / 3.
  • 30,000 x 25:56/37.
  • 5,000 x 50:33 / 14.
  • 5,000 x 100:160 / 81.
  • 10,000 x 200:1,924/772


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ऑरैकल में चुनिंदा क्वेरी के लिए डिफ़ॉल्ट पंक्ति क्रम

  2. Oracle 11g में ऑब्जेक्ट टाइप कॉलम से कैसे चुनें?

  3. Oracle में COMMIT पर ट्रिगर कैसे परिभाषित करें?

  4. Group_concat MySQL फ़ंक्शन Oracle में समतुल्य है

  5. त्रुटि:ORA-01704:स्ट्रिंग शाब्दिक बहुत लंबा