2015-12-15 47 views
5

Załóżmy, że mam tablicę ciągów tak:SQL: Wybierz ciągi, które mają jednakowe słowa

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

Chcę znaleźć ciągi, które mają jednakowe słowa. Zestaw wyników powinien być taki, jak:

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

lub przynajmniej coś takiego. Czy możesz pomóc?

+2

Co to jest RDBMS? Twój sposób dopasowywania wzorców tutaj, który niektóre RDBMS mają wbudowane w funkcje, które mogłyby pomóc. – xQbert

+0

@xQbert Używam Oracle 11g. – Mike

+0

Zobacz funkcje [UTL_Match] (https://docs.oracle.com/database/121/ARPLS/u_match.htm#ARPLS352). Jest tam kilka przyzwoitych funkcji dopasowywania. – xQbert

Odpowiedz

7

Jedną z metod jest użycie hack dla wyrażeń regularnych:

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

może chcesz sprawa być identyczne, a także:

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

Próbuję uruchomić to zapytanie, ale dostaję błąd, że t2 jest nieprawidłowym identyfikatorem (w części zamiennej). – Mike

+1

Myślę, że on oznacza t1.val i t2.val 'na regexp_like (t1.val, replace (t2.val, '', '|');' – xQbert

1

Możesz użyć kombinacji SUBSTRING i LIKE.

użyj charIndex (""), aby podzielić słowa w podciągu, jeśli to jest to, co chcesz zrobić.

1

Korzystanie niektóre [wewnętrznym similiarity oracle] stwierdzili, w UTL_Match (https://docs.oracle.com/database/121/ARPLS/u_match.htm#ARPLS71219) dopasowanie ...

Ta logika jest bardziej odpowiednia dla nazw lub opisów, które są "podobne" i gdzie fonetyczna pisownia lub literówka mogą powodować rekordy nie pasują.

Dostosowując .5 poniżej, możesz zobaczyć, w jaki sposób% 's przybliża Cię do idealnych dopasowań.

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 

oraz zrzut ekranu zapytania/wyjścia.

Albo moglibyśmy wykorzystać sprzężenie wewnętrzne i>, jeśli chcemy tylko jeden sposób compairisons ...

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 

ten zwraca 3 żądanych rekordów.

But this does not explicitly check each any word matches. co było Twoim podstawowym wymogiem. Chciałem tylko, żebyś był świadomy alternatyw.

enter image description here