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

कॉलम की निश्चित संख्या के साथ अल्पविराम से अलग किए गए मानों को लक्ष्य तालिका में विभाजित करें

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

अपनी वर्तमान स्थिति से रूबरू होते हुए ...

तत्वों की ज्ञात छोटी अधिकतम संख्या के लिए

प्रवंचना या पुनरावर्तन के बिना एक सरल उपाय करेगा:

SELECT id, 1 AS rnk
     , split_part(csv, ', ', 1) AS c1
     , split_part(csv, ', ', 2) AS c2
     , split_part(csv, ', ', 3) AS c3
     , split_part(csv, ', ', 4) AS c4
     , split_part(csv, ', ', 5) AS c5
FROM   tbl
WHERE  split_part(csv, ', ', 1) <> '' -- skip empty rows

UNION ALL
SELECT id, 2
     , split_part(csv, ', ', 6)
     , split_part(csv, ', ', 7)
     , split_part(csv, ', ', 8)
     , split_part(csv, ', ', 9)
     , split_part(csv, ', ', 10)
FROM   tbl
WHERE  split_part(csv, ', ', 6) <> '' -- skip empty rows

-- three more blocks to cover a maximum "around 20"

ORDER  BY id, rnk;

db<>fiddle यहां

id मूल तालिका का पीके होने के नाते।
यह स्पष्ट रूप से विभाजक के रूप में ',' मानता है।
आप आसानी से अनुकूलित कर सकते हैं।

संबंधित:

अज्ञात संख्या में तत्वों के लिए

विभिन्न तरीके। एक तरह से regexp_replace() का इस्तेमाल करें अननेस्टिंग से पहले हर पांचवें विभाजक को बदलने के लिए ...

-- for any number of elements
SELECT t.id, c.rnk
     , split_part(c.csv5, ', ', 1) AS c1
     , split_part(c.csv5, ', ', 2) AS c2
     , split_part(c.csv5, ', ', 3) AS c3
     , split_part(c.csv5, ', ', 4) AS c4
     , split_part(c.csv5, ', ', 5) AS c5
FROM   tbl t
     , unnest(string_to_array(regexp_replace(csv, '((?:.*?,){4}.*?),', '\1;', 'g'), '; ')) WITH ORDINALITY c(csv5, rnk)
ORDER  BY t.id, c.rnk;

db<>fiddle यहां

यह मानता है कि चुना गया विभाजक ; कभी नहीं आपके तार में दिखाई देता है। (जैसे , कभी प्रकट नहीं हो सकता।)

रेगुलर एक्सप्रेशन पैटर्न कुंजी है:'((?:.*?,){4}.*?),'

(?:) ... “नॉन-कैप्चरिंग” कोष्ठकों का सेट
() ... “कैप्चरिंग” कोष्ठकों का सेट
*? ...
गैर लालची परिमाणक
{4}? ... ठीक 4 मैचों का क्रम

प्रतिस्थापन '\1;' इसमें बैक-रेफरेंस शामिल है। \1

'g' चौथा फ़ंक्शन पैरामीटर बार-बार बदलने के लिए आवश्यक है।

आगे पढ़ना:

इसे हल करने के अन्य तरीकों में एक पुनरावर्ती CTE या एक सेट-रिटर्निंग फ़ंक्शन शामिल है ...

दाएं से बाएं भरें

(जैसे आपने दाईं ओर से शुरू होने वाले मानों को कॉलम में कैसे रखा जाए? में जोड़ा है। )
बस संख्याओं की गिनती करें जैसे:

SELECT t.id, c.rnk
     , split_part(c.csv5, ', ', 5) AS c1
     , split_part(c.csv5, ', ', 4) AS c2
     , split_part(c.csv5, ', ', 3) AS c3
     , split_part(c.csv5, ', ', 2) AS c4
     , split_part(c.csv5, ', ', 1) AS c5
FROM ...

db<>fiddle यहां



  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. मैं GeoDjango/PostGIS के साथ Enforce_srid_coordinate बाधा को कैसे संतुष्ट करूं?

  3. PostgreSQL में DROPping करते समय संदर्भित तालिकाओं पर अनन्य एक्सेस लॉक से बचें

  4. टाइपओआरएम ट्रांसफॉर्मर के साथ ऑपरेटर खोजें

  5. Django उत्पादन के लिए ऑटो-वृद्धि पीके/आईडी फ़ील्ड रीसेट करें