सीएसवी मानों को एक कॉलम में स्टोर करने के लिए यह आमतौर पर खराब डिज़ाइन है। यदि संभव हो तो, इसके बजाय एक सरणी या उचित सामान्यीकृत डिज़ाइन का उपयोग करें।
अपनी वर्तमान स्थिति से रूबरू होते हुए ...
तत्वों की ज्ञात छोटी अधिकतम संख्या के लिए
प्रवंचना या पुनरावर्तन के बिना एक सरल उपाय करेगा:
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'
चौथा फ़ंक्शन पैरामीटर बार-बार बदलने के लिए आवश्यक है।
आगे पढ़ना:
- PostgreSQL और regexp_split_to_array + unnestए>
- लागू करें ` टेक्स्ट ऐरे पर ट्रिम ()` और `regexp_replace ()`
- PostgreSQL unnest() एलिमेंट नंबर के साथए>
इसे हल करने के अन्य तरीकों में एक पुनरावर्ती 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 यहां