2016-06-10 46 views
3

有什么方法可以在列中找到类似的结果。例如:SQL - 列中的类似数据

enter image description here

我想从表中的数据,而不4绿树查询回报,因为没有类似的数据,以绿色的树,但蓝色轿车相似,蓝色的轿车和红色娃娃相似,红色小车。

enter image description here

如何做到这一点?

我使用Microsoft SQL Server同治工作室

+6

你必须定义什么是 “相似性”,是它的编辑距离?或者soundex?我认为你的目标是更简单的方法,如前三个字母组的平等? – Gar

回答

4

你可以使用SOUNDEX做到这一点。

样本数据;

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') 

下面的代码将使用soundexcolumn2创建类似的条目列表。然后它使用不同的子查询来查看该字段出现的次数。

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 

结果是这样的(我已经离开了soundex领域中向你展示它是什么样子);

GroupingField Title  SimilarFields 
B400   blue cars 2 
R300   red dolly 2 

soundexhttps://msdn.microsoft.com/en-gb/library/ms187384.aspx

编辑一些进一步阅读:根据您的要求,让你不妨推到一个临时表的原始数据,更改查询我给你把一个INTO之前FROM声明;

SELECT 
a.GroupingField 
,a.Title 
,b.SimilarFields 
INTO #Duplicates 
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 

然后使用以下查询链接回您的原始数据;

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 

会给出以下结果;

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 

记住

DROP TABLE #Differences 
+0

谢谢,就是这样。我只有一个问题。如何修改代码以查看哪些数据包含在分组中,以查看蓝色汽车2,蓝色汽车2,红色玩偶2,红色小车2 – pape

+0

您可以将此查询包含在外部查询中,也可以将此结果推送到一个临时表,然后根据soundex链接回你的原始数据。如果答案符合您的需求,请随时注册并将答案标记为已接受。 –

+0

好的,我粘贴了完整的查询。编辑后使用代码。请注意,您必须匹配您的数据(我的称为#SampleData,您的数据会有所不同)。如果你多次运行这个代码,你还需要在代码的最后加上DROP TABLE #Differences –

1

由于雀鳝理所当然地评论说,你必须定义什么叫“相似性”的意思。 但是,如果你需要的是(在你的例子8)相同字符的只是一些固定的号码,你可以做到以下几点:

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

这种方法使用相似的一个非常基本的概念,但可以扩展到一个更好的定义。这不是很有效率,请介意。 count(1) + 1包含基本短语。

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 

结果:

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