2016-06-10 6 views
3

Gibt es eine Möglichkeit, ähnliche Ergebnisse in Spalte zu finden. Beispiel:SQL - ähnliche Daten in Spalte

enter image description here

Ich mag Abfrage Rückkehr aus Tabellendaten ohne 4 grünen Baum, weil es keine ähnlichen Daten zu grünem Baum ist, aber blaues Auto ist ähnlich wie blaue Autos und rote Puppe ist ähnlich rote Dolly.

enter image description here

Wie dies zu tun?

Ich verwende Microsoft SQL Server Managment Studio

+6

Sie würden definieren, was "Ähnlichkeit" ist es der Levenstein Entfernung? oder der Soundex? Ich denke, dass Sie eher einen einfacheren Ansatz wie die Gleichheit der ersten drei Buchstabengruppen anstreben? – Gar

Antwort

4

Sie SOUNDEX dies zu tun, verwenden könnte.

Beispieldaten;

CREATE TABLE #SampleData (Column1 int, Column2 varchar(10)) 
INSERT INTO #SampleData (Column1, Column2) 
VALUES 
(1,'blue car') 
,(2,'red doll') 
,(3,'blue cars') 
,(4,'green tree') 
,(5,'red dolly') 

Der folgende Code wird soundex verwenden, um eine Liste von ähnlichen Einträgen in column2 zu erstellen. Es verwendet dann eine andere Unterabfrage, um zu sehen, wie viele Vorkommen dieses soundex Felds erscheinen;

SELECT 
a.GroupingField 
,a.Title 
,b.SimilarFields 
FROM (
     SELECT 
     SOUNDEX(Column2) GroupingField 
     ,MAX(Column2) Title --Just return a unique title for this soundex group 
     FROM #SampleData 
     GROUP BY SOUNDEX(Column2) 
    ) a 
LEFT JOIN (
       SELECT 
       SOUNDEX(Column2) GroupingField 
       ,COUNT(Column2) SimilarFields --How many fields are in the soundex group? 
       FROM #SampleData 
       GROUP BY SOUNDEX(Column2) 
      ) b 
ON a.GroupingField = b.GroupingField 
WHERE b.SimilarFields > 1 

Die Ergebnisse sehen wie folgt aus (ich habe das soundex Feld links in Ihnen zu zeigen, wie es aussieht);

GroupingField Title  SimilarFields 
B400   blue cars 2 
R300   red dolly 2 

Einige weitere Lesung am soundexhttps://msdn.microsoft.com/en-gb/library/ms187384.aspx

Edit: wie pro Ihren Antrag, die Originaldaten erhalten Sie auch in eine temporäre Tabelle schieben kann, um die Abfrage ich Ihnen gegeben habe, ändern ein setzen INTO vor der FROM Aussage;

Verwenden Sie dann die folgende Abfrage, um zurück zu Ihren ursprünglichen Daten zu verknüpfen;

SELECT 
a.GroupingField 
,a.Title 
,a.SimilarFields 
,b.Column1 
,b.Column2 
FROM #Duplicates a 
JOIN #SampleData b 
ON a.GroupingField = SOUNDEX(b.Column2) 
ORDER BY a.GroupingField 

würde das folgende Ergebnis geben; Denken Sie daran,

GroupingField Title  SimilarFields Column1  Column2 
B400   blue cars 2    1   blue car 
B400   blue cars 2    3   blue cars 
R300   red dolly 2    5   red dolly 
R300   red dolly 2    2   red doll 

zu

DROP TABLE #Differences 
+0

Danke, das ist es. Ich habe nur eine Frage. wie man Code ändert, um zu sehen, welche Daten in der Gruppierung enthalten sind, um blaue Autos 2, blaues Auto 2, rote Puppe 2, roter Dolly 2 zu sehen – pape

+0

Sie können diese Abfrage entweder in eine äußere Abfrage einfügen oder Sie können die Ergebnisse in diese schieben eine temporäre Tabelle und verlinken Sie dann zu Ihren ursprünglichen Daten basierend auf dem Soundex. Wenn die Antwort Ihren Anforderungen entspricht, können Sie die Antwort positiv bewerten und als akzeptiert markieren. –

+0

Ok, ich habe die vollständige Abfrage eingefügt. Verwenden Sie den Code nach der Bearbeitung. Beachten Sie, dass Sie Ihre Daten anpassen müssen (meine heißt #SampleData, Ihre wird anders sein). Wenn Sie das mehrmals ausführen, müssen Sie DROP TABLE #Differences auch am Ende Ihres Codes ablegen –

1

Wie Gar zu Recht bemerkt, müssen Sie bestimmen, was Sie mit "Ähnlichkeit" bedeuten. Aber wenn alles, was Sie brauchen nur einige feste Anzahl (8 in Ihrem Beispiel) gleichen Zeichen ist, können Sie folgendes tun:

create table myTest 
(
    id int, 
    name varchar(20) 
); 

insert into myTest values(1, 'blue car'); 
insert into myTest values(2, 'red doll'); 
insert into myTest values(3, 'blue cars'); 
insert into myTest values(4, 'green tree'); 
insert into myTest values(5, 'red dolly'); 

select left(name,8), count(*) 
from myTest 
group by left(name,8) 
having count(*) > 1; 
0

Dieser Ansatz einen sehr grundlegenden Begriff der Ähnlichkeit verwendet, sondern kann auf eine bessere Definition erweitert werden. Es ist nicht sehr effizient, wohlgemerkt. Die count(1) + 1 enthält die Basisphrase.

create table phrases (phrase varchar(max)) 
insert phrases values('blue car'), ('blue cars'), ('green tree'), ('red doll'), ('red dolly') 

create function dbo.fnSimilar(@s1 varchar(max), @s2 varchar(max)) 
returns int 
begin 
    if @s1 = @s2 return 0 -- a phrase is not similar to itself 
    if @s1 like @s2 + '%' return 1 
    if @s2 like @s1 + '%' return 2 
    return 0 
end 

select x.phrase, similar = count(1) + 1 from 
(
    select p1.phrase from phrases p1 
    inner join phrases p2 on dbo.fnSimilar(p2.phrase, p1.phrase) = 1 
) x 
group by x.phrase 

Ergebnis:

phrase  similar 
-------- ------- 
blue car 2 
red doll 2 
Verwandte Themen