2011-12-21 16 views

उत्तर

45

सीएसवी में फ़ील्ड की संख्या तो स्थिर है, तो आप कुछ इस तरह कर सकता है:

select a[1], a[2], a[3], a[4] 
from (
    select regexp_split_to_array('a,b,c,d', ',') 
) as dt(a) 

उदाहरण के लिए:

=> select a[1], a[2], a[3], a[4] from (select regexp_split_to_array('a,b,c,d', ',')) as dt(a); 
a | a | a | a 
---+---+---+--- 
a | b | c | d 
(1 row) 

तो सीएसवी में फ़ील्ड की संख्या स्थिर नहीं है तो आप इस तरह कुछ के साथ फ़ील्ड की अधिकतम संख्या प्राप्त कर सकते हैं:

select max(array_length(regexp_split_to_array(csv, ','), 1)) 
from your_table 

और फिर बी अपनी क्वेरी के लिए उपयुक्त a[1], a[2], ..., a[M] कॉलम सूची बनाएं। तो अगर ऊपर आप 6 की एक अधिकतम दे दी है, तो आप इस का उपयोग करेंगे:

select a[1], a[2], a[3], a[4], a[5], a[6] 
from (
    select regexp_split_to_array(csv, ',') 
    from your_table 
) as dt(a) 

यदि आप चाहते थे एक समारोह में उन दो प्रश्नों जोड़ सकता।

उदाहरण के लिए, इस डेटा दे (कि अंतिम पंक्ति में एक शून्य है):

=> select * from csvs; 
    csv  
------------- 
1,2,3 
1,2,3,4 
1,2,3,4,5,6 

(4 rows) 

=> select max(array_length(regexp_split_to_array(csv, ','), 1)) from csvs; 
max 
----- 
    6 
(1 row) 

=> select a[1], a[2], a[3], a[4], a[5], a[6] from (select regexp_split_to_array(csv, ',') from csvs) as dt(a); 
a | a | a | a | a | a 
---+---+---+---+---+--- 
1 | 2 | 3 | | | 
1 | 2 | 3 | 4 | | 
1 | 2 | 3 | 4 | 5 | 6 
    | | | | | 
(4 rows) 

के बाद से अपने सीमांकक एक सरल तय स्ट्रिंग है, आप भी string_to_array बजाय regexp_split_to_array का इस्तेमाल कर सकते हैं:

select ... 
from (
    select string_to_array(csv, ',') 
    from csvs 
) as dt(a); 

इस फ़ंक्शन के बारे में अनुस्मारक के लिए Michael पर धन्यवाद।

यदि संभव हो तो सीएसवी कॉलम से बचने के लिए आपको वास्तव में अपने डेटाबेस स्कीमा को फिर से डिजाइन करना चाहिए। आपको इसके बजाय सरणी कॉलम या एक अलग तालिका का उपयोग करना चाहिए।

+0

धन्यवाद की जाँच करें और वापस लौटने जाएगा – Gallop

+6

'का उपयोग कर' regexp_split_to_array' के बजाय string_to_array' पर विचार करें; यह तेज़ होना चाहिए क्योंकि इसमें नियमित अभिव्यक्ति प्रसंस्करण का ओवरहेड नहीं है। – Michael

+1

@ माइकल यदि आप चाहें तो इसे एक और जवाब के रूप में जोड़ सकते हैं। या मैं अपने में एक विकल्प के रूप में 'string_to_array' जोड़ सकता हूं, यह सुनिश्चित नहीं करता कि मुझे यह कैसे याद आया। –

64

split_part() क्या आप एक कदम में चाहते हैं करता है: के रूप में आप col (अधिकतम संभव) में आइटम नहीं हैं

SELECT split_part(col, ',', 1) AS col1 
    , split_part(col, ',', 2) AS col2 
    , split_part(col, ',', 3) AS col3 
    , split_part(col, ',', 4) AS col4 
FROM tbl; 

के रूप में कई लाइनों जोड़ें। डेटा आइटम से अधिक कॉलम खाली तार होंगे ('')।

+4

और regexp_split_to_array संस्करण की तुलना में बहुत तेज निष्पादित प्रतीत होता है। –

+0

@ जॉनबार्का: सभी नियमित अभिव्यक्ति फ़ंक्शन अपेक्षाकृत महंगे होते हैं। शक्तिशाली, लेकिन कीमत के लिए ... –

+4

किंवदंती! यह इस तरह के मुद्दे के लिए सबसे तेज़ दृष्टिकोण है। –

1

आप विभाजन समारोह का उपयोग कर सकते हैं।

SELECT 
    (select top 1 item from dbo.Split(FullName,',') where id=1) Column1, 
    (select top 1 item from dbo.Split(FullName,',') where id=2) Column2, 
    (select top 1 item from dbo.Split(FullName,',') where id=3) Column3, 
    (select top 1 item from dbo.Split(FullName,',') where id=4) Column4, 
    FROM MyTbl 
संबंधित मुद्दे