यहां एक समाधान है जो केवल मानक स्ट्रिंग फ़ंक्शंस (नियमित अभिव्यक्तियों के बजाय) का उपयोग करता है - जिसके परिणामस्वरूप अधिकांश मामलों में तेजी से निष्पादन होना चाहिए; यह केवल 3 को हटाता है जब यह पहला वर्ण होता है जिसके बाद अल्पविराम होता है, अंतिम वर्ण अल्पविराम से पहले होता है, या पहले और उसके बाद अल्पविराम होता है, और यह अल्पविराम को हटा देता है जो इसके बाद के अल्पविराम को हटा देता है और यह अल्पविराम को हटा देता है। पहला और तीसरा मामला।
यह एक पंक्ति में दो 3 को हटाने में सक्षम है (जो कि पेश किए गए कुछ अन्य समाधान करने में सक्षम नहीं हैं) जबकि लगातार अल्पविराम (जो संभवतः NULL के लिए खड़े होते हैं) छोड़ते हैं और 38 या 123 जैसी संख्याओं को परेशान नहीं करते हैं।पी>
रणनीति यह है कि पहले प्रत्येक अल्पविराम को दोगुना किया जाए (,
. को बदलें) ,,
. के साथ ) और एक अल्पविराम (स्ट्रिंग की शुरुआत और अंत तक) को जोड़ें और तैयार करें। फिर ,3,
. की हर घटना को हटा दें . जो बचा है, उसमें से प्रत्येक ,,
. को बदलें एक ,
. के साथ वापस और अंत में अग्रणी और अनुगामी ,
. को हटा दें ।
with
test_data ( str ) as (
select '1,2,3,4,5' from dual union all
select '1,2,3,3,4,4,5' from dual union all
select '12,34,5' from dual union all
select '1,,,3,3,3,4' from dual
)
select str,
trim(both ',' from
replace( replace(',' || replace(str, ',', ',,') || ',', ',3,'), ',,', ',')
) as new_str
from test_data
;
STR NEW_STR
------------- ----------
1,2,3,4,5 1,2,4,5
1,2,3,3,4,4,5 1,2,4,4,5
12,34,5 12,34,5
1,,,3,3,3,4 1,,,4
4 rows selected.
नोट जैसा कि MT0 द्वारा बताया गया है (नीचे टिप्पणियाँ देखें), यदि मूल स्ट्रिंग अल्पविराम से शुरू या समाप्त होती है तो यह बहुत अधिक ट्रिम हो जाएगी। उस मामले को कवर करने के लिए, trim(both ',' from ...)
. के भीतर सब कुछ लपेटने के बजाय मुझे बाकी को सबक्वायरी में लपेटना चाहिए, और substr(new_str, 2, length(new_str) - 2)
जैसी किसी चीज़ का उपयोग करना चाहिए बाहरी क्वेरी में।