2015-12-15 32 views
5

Supponiamo che io ho una tabella di stringhe, in questo modo:SQL: Selezionare le stringhe che hanno uguali parole

VAL 
----------------- 
Content of values 
Values identity 
Triple combo 
my combo 
sub-zero combo 

voglio trovare stringhe che hanno uguali parole. Il set di risultati dovrebbe essere come

VAL    MATCHING_VAL 
------------------ ------------------ 
Content of values Values identity 
Triple combo  My combo 
Triple combo  sub-zero combo 

o almeno qualcosa di simile. Potete aiutare?

+2

Cosa RDBMS è questo? Stai facendo alcuni pattern matching qui che alcuni RDBMS hanno incorporato in funzioni che potrebbero aiutare. – xQbert

+0

@xQbert Sto usando Oracle 11g. – Mike

+0

Guarda le funzioni [UTL_Match] (https://docs.oracle.com/database/121/ARPLS/u_match.htm#ARPLS352). Ci sono alcune funzioni di corrispondenza decenti lì. – xQbert

risposta

7

Un metodo è quello di utilizzare un hack per le espressioni regolari:

select t1.val, t2.val 
from t t1 join 
    t t2 
    on regexp_like(t1.val, replace(t2.val, ' ', '|'); 

Si potrebbe desiderare il caso di essere identico così:

 on regexp_like(lower(t1.val), replace(lower(t2.val), ' ', '|'); 
+0

Sto tentando di eseguire questa query, ma sto ricevendo errore che t2 è un identificatore non valido (nella parte di sostituzione). – Mike

+1

Penso che significhi t1.val e t2.val 'su regexp_like (t1.val, replace (t2.val, '', '|');' – xQbert

1

È possibile utilizzare una combinazione di SUBSTRING e LIKE.

utilizzare charIndex ("") per dividere le parole nella sottostringa se questo è ciò che si desidera fare.

1

Utilizzando alcuni dei [similiarity interna Oracle] trovato in UTL_Match (https://docs.oracle.com/database/121/ARPLS/u_match.htm#ARPLS71219) corrispondente a ...

Questa logica è più per la corrispondenza di nomi o descrizioni che sono "Simili" e dove l'ortografia fonetica o l'errore di battitura possono causare t registra per non abbinare.

Regolando il .5 in basso puoi vedere come il% ti avvicina sempre di più alle corrispondenze perfette.

with cte as (
select 'Content of values' val from dual union all 
select 'Values identity' val from dual union all 
select 'triple combo' from dual union all 
select 'my combo'from dual union all 
select 'sub-zero combo'from dual) 

select a.*, b.*, utl_match.edit_distance_similarity(a.val, b.val) c, UTL_MATCH.JARO_WINKLER(a.val,b.val) JW 
from cte a 
cross join cte b 
where UTL_MATCH.JARO_WINKLER(a.val,b.val) > .5 
order by utl_match.edit_distance_similarity(a.val, b.val) desc 

e schermata di query/output.

O potremmo utilizzare un inner join e> se vogliamo solo compairisons un modo ...

select a.*, b.*, utl_match.edit_distance_similarity(a.val, b.val) c, UTL_MATCH.JARO_WINKLER(a.val,b.val) JW 
from cte a 
inner join cte b 
    on A.Val > B.Val 
where utl_match.jaro_winkler(a.val,b.val) > .5 
order by utl_match.edit_distance_similarity(a.val, b.val) desc 

questa restituisce i 3 record desiderati.

But this does not explicitly check each any word matches. che era il vostro requisito di base. Volevo solo che tu fossi consapevole delle alternative.

enter image description here