आप तालिका (ओं) को पहले सामान्य रूप में प्राप्त कर सकते हैं और फिर प्रत्येक पंक्ति में संग्रहीत यौगिकों की तुलना कर सकते हैं। एक प्रारंभिक बिंदु हो सकता है:
{1} प्रत्येक पंक्ति को टोकननाइज़ करें, और टोकन को एक नई तालिका में लिखें। प्रत्येक टोकन को उसकी मूल आईडी प्लस दें एक 3-अक्षर उपसर्ग, यह दर्शाता है कि टोकन किस तालिका से आया है। {2} नई ("सामान्यीकृत") तालिका की पंक्तियों को आईडी द्वारा समूहित करें, और एक LISTAGG () निष्पादित करें। सेल्फ़ जॉइन करें, और मिलते-जुलते "टोकन समूह" ढूंढें।
{1} टोकनाइज़ करें, चयन के रूप में तालिका बनाएं (CTAS)
create table tokens
as
select
ltrim( -- ltrim() and rtrim() remove leading/trailing spaces (blanks)
rtrim(
substr( N.wrapped
, instr( N.wrapped, ',', 1, T.pos ) + 1
, ( instr( N.wrapped, ',', 1, T.pos + 1 ) - instr( N.wrapped, ',', 1, T.pos ) ) - 1
)
)
) token
, N.id
from (
select ',' || name1 || ',' as wrapped, 'T1_' || to_char( id_t1 ) as id from t1 -- names wrapped in commas, (table)_id
union all
select ',' || name2 || ',' , 'T2_' || to_char( id_t2 ) from t2
) N join (
select level as pos -- (max) possible position of char in an existing token
from dual
connect by level <= (
select greatest( -- find the longest string ie max position (query T1 and T2)
( select max( length( name1 ) ) from t1 )
, ( select max( length( name2 ) ) from t2 )
) as pos
from dual
)
) T
on T.pos <= ( length( N.wrapped ) - length( replace( N.wrapped, ',') ) ) - 1
;
CONNECT BY का उपयोग किए बिना टोकन करने की प्रेरणा इस SO उत्तर से मिली है। ।
टोकन तालिका की सामग्री कुछ इस तरह दिखाई देगी:
SQL> select * from tokens ;
TOKEN ID
ASCORBIC ACID T1_1
SODIUM HYDROGEN CARBONATE T1_2
CAFFEINE T1_3
PSEUDOEPHEDRINE HYDROCHLORIDE T1_4
PARACETAMOL T1_100
sodium hydroxide T1_110
POTASSIUM HYDROGEN CARBONATE T2_4
SODIUM HYDROGEN CARBONATE T2_5
PARACETAMOL PH. EUR. T2_6
CODEINE PHOSPHATE T2_7
DEXCHLORPHENIRAMINE MALEATE T2_8
DEXCHLORPHENIRAMINE MALEATE T2_10
PARACETAMOL T2_200
...
{2} GROUP BY, LISTAGG, स्वयं शामिल हों
select
S1.id id1
, S2.id id2
, S1.tokengroup_T1
, S2.tokengroup_T2
from
(
select substr( id, 4, length( id ) - 3 ) id
, listagg( token, ' + ' ) within group ( order by token ) tokengroup_T1
from tokens
group by id
having substr( id, 1, 3 ) = 'T1_'
) S1
join
(
select substr( id, 4, length( id ) - 3 ) id
, listagg( token, ' + ' ) within group ( order by token ) tokengroup_T2
from tokens
group by id
having substr( id, 1, 3 ) = 'T2_'
) S2
on S1.tokengroup_T1 = S2.tokengroup_T2
;
-- result
ID1 ID2 TOKENGROUP_T1 TOKENGROUP_T2
4 10 DEXCHLORPHENIRAMINE MALEATE + PSEUDOEPHEDRINE HYDROCHLORIDE DEXCHLORPHENIRAMINE MALEATE + PSEUDOEPHEDRINE HYDROCHLORIDE
110 210 potassium carbonate + sodium hydroxide potassium carbonate + sodium hydroxide
1 4 ASCORBIC ACID + PARACETAMOL + POTASSIUM HYDROGEN CARBONATE ASCORBIC ACID + PARACETAMOL + POTASSIUM HYDROGEN CARBONATE
3 6 CAFFEINE + PARACETAMOL PH. EUR. CAFFEINE + PARACETAMOL PH. EUR.
चीजों को इस तरह से करते समय, आप पदार्थों को (वर्णमाला) क्रम में प्राप्त कर सकते हैं, और आप यहां एक "सीमांकक" भी चुन सकते हैं जो आपको पसंद है (हमने '+' का उपयोग किया है)।
वैकल्पिक
यदि वह सब आपके काम नहीं आता है, या आपको लगता है कि यह बहुत जटिल है, तो आप TRANSLATE() का उपयोग करने का प्रयास कर सकते हैं। इस मामले में, मैं आपके डेटासेट से सभी रिक्त स्थान/रिक्त स्थान निकालने की अनुशंसा करता हूं (एक प्रश्न में - नहीं मूल डेटा को बदलना!) जैसे:
क्वेरी
select
id1, id2
, name1, name2
from (
select
id_t1 id1
, id_t2 id2
, T1.name1 name1
, T2.name2 name2
from T1
join T2
on translate( replace( T1.name1, ' ', '' ), replace( T2.name2, ' ', '' ), '!' )
= translate( replace( T2.name2, ' ', '' ), replace( T1.name1, ' ', '' ), '!' )
) ;
परिणाम
ID1 ID2 NAME1 NAME2
2 5 SODIUM HYDROGEN CARBONATE, SODIUM CARBONATE ANHYDROUS, CITRIC ACID SODIUM HYDROGEN CARBONATE, SODIUM CARBONATE ANHYDROUS
3 6 CAFFEINE, PARACETAMOL PH. EUR. PARACETAMOL PH. EUR.,CAFFEINE
100 10 PARACETAMOL, DEXTROMETHORPHAN, PSEUDOEPHEDRINE, PYRILAMINE DEXCHLORPHENIRAMINE MALEATE, PSEUDOEPHEDRINE HYDROCHLORIDE
110 210 sodium hydroxide, potassium carbonate sodium hydroxide, potassium carbonate
नोट: मैंने आपके नमूना डेटा में निम्नलिखित पंक्तियां जोड़ दी हैं:
-- T1
110, 'sodium hydroxide, potassium carbonate'
-- T2
210, 'sodium hydroxide, potassium carbonate'
211, 'potassium hydroxide, sodium carbonate'
मैंने पाया कि ट्रांसलेट() को इस तरह से उपयोग करना आसान है जो आपको "झूठी सकारात्मक" देता है यानी 110, 210, और 211 वाले पदार्थ "मिलान" दिखाई देंगे। (दूसरे शब्दों में:मुझे नहीं लगता कि यह इस काम के लिए सही उपकरण है।)
(नमूना तालिकाओं और प्रश्नों को देखने के लिए लिंक का अनुसरण करें)।