SQL获取具有类似列值的行

时间:2014-02-06 08:35:43

标签: asp.net sql sql-server

我有一个数据库,有时会存储重复的行,但副本不是明确的,例如以下两列值将是重复的:

G12345 & G1234 --> because they are very similar 
(a string comparison shows that the characters match 83.3%).

我需要一些帮助来编写SQL查询,该查询将检索与作为查询的一部分发送的字符串非常相似的值,例如超过50%的人物匹配。

有人可以帮忙吗?我有一个C#方法如下,但不太确定如何在SQL中完成此任务:

static double StringCompare(string a, string b)
{
  if (a == b) //Same string, no iteration needed.
    return 100;
  if ((a.Length == 0) || (b.Length == 0)) //One is empty, second is not
  {
    return 0;
  }
  var maxLen = a.Length > b.Length ? a.Length : b.Length;
  var minLen = a.Length < b.Length ? a.Length : b.Length;
  var sameCharAtIndex = 0;
  for (var i = 0; i < minLen; i++) //Compare char by char
  {
    if (a[i] == b[i])
    {
      sameCharAtIndex++;
    }
  }
  return sameCharAtIndex / maxLen * 100;
}

提前致谢。

2 个答案:

答案 0 :(得分:0)

使用Mysql Like Operator而不是在服务层中进行。

SELECT * FROM table WHERE column LIKE 'G12___' or 'G12%'.

SELECT * FROM table WHERE column LIKE '%input string as parameter%'.

LIKE谓词中的“_”通配符表示“任何一个字符”,相当于“。”在正则表达式中。

请参阅this以供参考。

答案 1 :(得分:0)

不确定您是否尝试使用SQL-Server或MySQL,但您可以在SQL-Server中创建并使用以下函数:

create function StringCompare
    (@A nvarchar(200),
    @B nvarchar(200)
    )
returns float
as
begin
    if (
        @A = @B
        or (@A is null and @B is null)
        )
    begin
        return 100.0
    end

    if (
        ((@A is null or len(@A) = 0) and (@B is not null and len(@B) > 0))
        or ((@B is null or len(@B) = 0) and (@A is not null and len(@A) > 0))
        )
    begin
        return 0.0
    end

    declare @maxLen int
    set @maxLen = case when len(@A) > len(@B) then len(@A) else len(@B) end

    declare @minLen int
    set @minLen = case when len(@A) < len(@B) then len(@A) else len(@B) end

    declare @sameCharAtIndex int
    set @sameCharAtIndex = 0

    declare @count int
    set @count = 1

    while (@count <= @minLen)
    begin
        if (SUBSTRING(@A, @count, 1) = substring(@B, @count, 1))
        begin
            set @sameCharAtIndex = @sameCharAtIndex + 1
        end

        set @count = @count + 1
    end

    return cast(@sameCharAtIndex as float) / cast(@maxLen as float) * 100.0

end

可以在任何声明中使用,如下所示:

select dbo.StringCompare('test', 'test'), dbo.StringCompare('nope', 'test'),  dbo.StringCompare('partial', 'parsomethingelse')

请注意,在许多记录上运行的sql中有这样的循环可能效率低下。您可能想要考虑是否真的必须在sql中执行此操作。