मैं टोकन 'ईडर:' के बाद मेल पते निकालने की कोशिश कर रहा हूं। तो यह लाइन प्रविष्टियों में सभी घटनाओं से मेल खाएगा, उस टोकन के बाद रिक्त स्थान के बिना पहली लगातार स्ट्रिंग: मैंने कोशिश की:
SELECT regexp_substr(tab.entry, 'eaddr:\(.*?\)',1,1,'e',1)
from (
select 'String, email@domain.com' as entry
union
select 'eaddr:mail1@domain.com eaddr:mail2@domain.com sometext eaddr: mail3@domain.com some4354% text' as entry
union
select 'eaddr:mail5@domain.org' as entry
union
select 'Just a string' as entry
) tab
;
लेकिन इससे काम नहीं होता। सही परिणाम सेट है:
null
mail1@domain.com mail2@domain.com mail3@domain.com
mail5@domain.org
null
4 जवाब
सबसे पहले, मैं ईमेल प्रारूप को सत्यापित करने के लिए बेहतर रेगेक्स का उपयोग करने का सुझाव देता हूं। मैं गॉर्डन के SPLIT_TO_TABLE + LATERAL दृष्टिकोण से प्रेरित हूं, और उन ईमेल को प्रविष्टियों से लाने के लिए कुछ नमूना प्रश्न लिखे हैं।
यदि आप सभी ईमेल एक साथ प्राप्त करना चाहते हैं, तो आप इसका उपयोग कर सकते हैं:
with t as (
select 'String, email@domain.com' as entry
union
select 'eaddr:mail1@domain.com eaddr:mail2@domain.com sometext eaddr: mail3@domain.com some4354% text' as entry
union
select 'eaddr:mail5@domain.org' as entry
union
select 'Just a string' as entry
)
Select LISTAGG( regexp_substr( s.value, '[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}' ) ,' ' ) emails from t,
lateral SPLIT_TO_TABLE(t.entry, 'eaddr:') s
where s.seq > 1;
+---------------------------------------------------------------------+
| EMAILS |
+---------------------------------------------------------------------+
| mail1@domain.com mail2@domain.com mail3@domain.com mail5@domain.org |
+---------------------------------------------------------------------+
अपने प्रश्न में सटीक परिणाम प्राप्त करने के लिए, आप निम्न क्वेरी का उपयोग कर सकते हैं:
with t as (
select 'String, email@domain.com' as entry
union
select 'eaddr:mail1@domain.com eaddr:mail2@domain.com sometext eaddr: mail3@domain.com some4354% text' as entry
union
select 'eaddr:mail5@domain.org' as entry
union
select 'Just a string' as entry
)
select emails from
(
Select t.entry, s.*,
LISTAGG( regexp_substr( IFF(s.seq = 1, '', s.value ), '[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}' ) ,' ' )
OVER ( PARTITION BY s.seq ) emails
from t,
lateral SPLIT_TO_TABLE(t.entry, ' ') s )
where index = 1;
+----------------------------------------------------+
| EMAILS |
+----------------------------------------------------+
| NULL |
| mail1@domain.com mail2@domain.com mail3@domain.com |
| NULL |
| mail5@domain.org |
+----------------------------------------------------+
जावास्क्रिप्ट यूडीएफ का उपयोग करना
create or replace function ext_mail(col VARCHAR)
returns varchar
language javascript
as
$$
var y = COL.match(/(?!eaddr):(\s+)?\w+@\w+/g);
if (y) {
ext_out = y.join(' ');
return ext_out.replace(/:|\s+/g,' ')
}
else return 'NULL'
$$
;
with t as (
select 'String, email@domain.com' as entry
union
select 'eaddr:mail1@domain.com eaddr:mail2@domain.com sometext eaddr: mail3@domain.com some4354% text' as entry
union
select 'eaddr:mail5@domain.org' as entry
union
select 'Just a string' as entry
) select ext_mail(ENTRY) from t;
आपको स्ट्रिंग्स को विभाजित करने, ईमेल निकालने और फिर पुन: एकत्र करने की आवश्यकता है। मेरे पास स्नोफ्लेक नहीं है, लेकिन यह या ऐसा ही कुछ करना चाहिए:
select t.*, s.emails
from t left join lateral
(select list_agg(split(s.value, ' ')), ' ') as emails
from table(string_split_to_table(t.entry, 'eaddr:')) as s
) s;
मुझे 100% यकीन नहीं है कि स्नोफ्लेक उदाहरण के लिए बहु-वर्ण सीमांकक का समर्थन करता है। यदि ऐसा है, तो आप इसका उपयोग कर सकते हैं:
select t.*, s.emails
from t left join lateral
(select list_agg(substr(s.value, 7), ' ') as emails
from table(string_split_to_table(t.entry, ' ')) as s
where value like 'eaddr:%'
) s;
जहाँ तक मुझे पता है, आप REGEXP_SUBSTR से एक बार में केवल एक मैच लौटा सकते हैं। नीचे दिया गया कोड:
with tab(entry) as (
select 'String, email@domain.com' from dual
union
select 'eaddr:mail1@domain.com eaddr:mail2@domain.com sometext eaddr: mail3@domain.com some4354% text' from dual
union
select 'eaddr:mail5@domain.org' from dual
union
select 'Just a string' from dual
)
SELECT
regexp_substr(entry, 'eaddr:\s*(\S*)\s*',1,1,'i',1)
|| coalesce(' ' || regexp_substr(entry, 'eaddr:\s*(\S*)\s*',1,2,'i', 1), '')
|| coalesce(' ' || regexp_substr(entry, 'eaddr:\s*(\S*)\s*',1,3,'i', 1), '') as match,
regexp_count(entry, 'eaddr:\s*(\S*)\s*') as nmatches
from tab
नीचे परिणाम देता है (ओरेकल का उपयोग करके)। आप मिलानों की संख्या प्राप्त करने के लिए दिखाए गए अनुसार REGEXP_COUNT का उपयोग कर सकते हैं। यदि 3 से अधिक ईमेल पते हैं, तो आप आवश्यकतानुसार अधिक || coalesce(
पंक्तियाँ जोड़ सकते हैं।
पी.एस. मुझे यकीन नहीं है कि आपके उदाहरण में 'ई' ध्वज क्या करता है। मैं अनुमान लगा रहा हूं कि यह एक स्नोफ्लेक-विशिष्ट मान है।
संबंधित सवाल
नए सवाल
sql
संरचित क्वेरी भाषा (एसक्यूएल) डेटाबेस को क्वेरी करने के लिए एक भाषा है। प्रश्नों में कोड उदाहरण, तालिका संरचना, नमूना डेटा और DBMS कार्यान्वयन के लिए एक टैग (जैसे MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2, आदि) का उपयोग किया जाना चाहिए। यदि आपका प्रश्न केवल एक विशिष्ट DBMS (विशिष्ट एक्सटेंशन / सुविधाओं का उपयोग करता है) से संबंधित है, तो इसके बजाय उस DBMS के टैग का उपयोग करें। एसक्यूएल के साथ टैग किए गए सवालों के जवाब में आईएसओ / आईईसी मानक एसक्यूएल का उपयोग करना चाहिए।