2012-03-16 110 views
7

当我比较SQL Server中的两个字符串时,有几个简单的方法与=LIKE如何比较两个字符串在SQL Server 2008的T-SQL中是否包含相同的单词?

我要重新定义平等:

如果两个字符串包含相同的话 - 不管以什么顺序 - 他们是平等的,否则他们是不会。

例如:

  • 'my word''word my'相等
  • 'my word''aaamy word'

什么是对这个问题的最好简单的解决方案?

+0

1)不区分大小写的事?最有可能不是,但我想问,我应该问。 2)在另一个计数中存在的一个组中重复项目是否匹配?意思是说,“我的话”是否等于“说我的话”? – 2012-03-19 12:33:24

回答

4

我不认为有一个简单的解决方案,用于在SQL Server中尝试执行的操作。我首先想到的是创建一个CLR UDF是:

  1. 接受两个字符串
  2. 人把它们打破成两个阵列使用的“”
  3. 比较两个数组的内容,返回如果真的分割功能它们包含相同的元素。

如果这是您想要前往的路线,请查看this article以开始创建CLR UDF。

0

您可以在INSERT/UPDATE触发器(或UDF默认值)中计算的基表中添加一个预计算列,用于拆分,排序并连接来自原始列的单词。

然后使用=来比较这些预先计算的列。

1

情景如下。你会希望使用TVF在空间上分割第一个和第二个字符串,然后full join由此产生两个值表,如果左侧或右侧有空值,则表示不平等,否则它们相等。

0

有一个名为http://www.sqlsharp.com/的库,它包含了一整套有用的字符串/数学函数。

它有一个名为String_CompareSplitValues的函数,它正是你想要的。

我不确定它是社区版本还是付费版本。

0
declare @s1 varchar(50) = 'my word' 
declare @s2 varchar(50) = 'word my' 

declare @t1 table (word varchar(50)) 

while len(@s1)>0 
begin 
    if (CHARINDEX(' ', @s1)>0) 
    begin  
     insert into @t1 values(ltrim(rtrim(LEFT(@s1, charindex(' ', @s1)))))   
     set @s1 = LTRIM(rtrim(right(@s1, len(@s1)-charindex(' ', @s1)))) 
    end 
    else 
    begin 
     insert into @t1 values (@s1) 
     set @s1=''  
    end  
end 

declare @t2 table (word varchar(50)) 
while len(@s2)>0 
begin 
    if (CHARINDEX(' ', @s2)>0) 
    begin  
     insert into @t2 values(ltrim(rtrim(LEFT(@s2, charindex(' ', @s2)))))   
     set @s2 = LTRIM(rtrim(right(@s2, len(@s2)-charindex(' ', @s2)))) 
    end 
    else 
    begin 
     insert into @t2 values (@s2) 
     set @s2=''  
    end  
end 

select case when exists(SELECT * FROM @t1 EXCEPT SELECT * FROM @t2) then 'are not' else 'are equal' end 
+0

这不是单行查询的答案 – 2016-08-17 05:32:10

2

试试这个... StringSorter函数在空间上打断字符串,然后对所有单词进行排序,然后按照排序的单词顺序将字符串放回到一起。

CREATE FUNCTION dbo.StringSorter(@sep char(1), @s varchar(8000)) 
RETURNS varchar(8000) 
AS 
BEGIN 
    DECLARE @ResultVar varchar(8000); 

    WITH sorter_cte AS (
     SELECT CHARINDEX(@sep, @s) as pos, 0 as lastPos 
     UNION ALL 
     SELECT CHARINDEX(@sep, @s, pos + 1), pos 
     FROM sorter_cte 
     WHERE pos > 0 
    ) 
    , step2_cte AS (
    SELECT SUBSTRING(@s, lastPos + 1, 
      case when pos = 0 then 80000 
      else pos - lastPos -1 end) as chunk 
    FROM sorter_cte 
    ) 
    SELECT @ResultVar = (select ' ' + chunk 
            from step2_cte 
            order by chunk 
            FOR XML PATH('')); 
    RETURN @ResultVar; 
END 
GO 

下面是一个测试用例只是想出来的功能:

SELECT dbo.StringSorter(' ', 'the quick brown dog jumped over the lazy fox'); 

其产生这些结果:

brown dog fox jumped lazy over quick the the 

然后从SELECT语句中使用字符串运行

SELECT case when dbo.StringSorter(' ', 'my word') = 
        dbo.StringSorter(' ', 'word my') 
       then 'Equal' else 'Not Equal' end as ResultCheck 
SELECT case when dbo.StringSorter(' ', 'my word') = 
        dbo.StringSorter(' ', 'aaamy word') 
       then 'Equal' else 'Not Equal' end as ResultCheck 

第一次e表明他们是平等的,而第二个则没有。

这应该做你正在寻找与一个简单的函数利用递归CTE排序你的字符串。

享受!

1

一个非常简单的方法来做到这一点... JC65100

ALTER FUNCTION [dbo].[ITS_GetDifCharCount] 
(
@str1 VARCHAR(MAX) 
,@str2 VARCHAR(MAX) 
) 
RETURNS INT 
AS 
BEGIN 
DECLARE @result INT 

SELECT @result = COUNT(*) 
FROM dbo.ITS_CompareStrs(@str1,@str2) 

RETURN @result 

END 


ALTER FUNCTION [dbo].[ITS_CompareStrs] 
(
@str1 VARCHAR(MAX) 
,@str2 VARCHAR(MAX) 
) 
RETURNS 
@Result TABLE (ind INT, c1 char(1), c2 char(1)) 
AS 
BEGIN 
    DECLARE @i AS INT 
      ,@c1 CHAR(1) 
      ,@c2 CHAR(1) 

    SET @i = 1 

    WHILE LEN (@str1) > @i-1 OR LEN (@str2) > @i-1 
    BEGIN 

     IF LEN (@str1) > @i-1 
     SET @c1 = substring(@str1, @i, 1) 

     IF LEN (@str2) > @i-1 
     SET @c2 = substring(@str2, @i, 1) 

     INSERT INTO @Result([ind],c1,c2) 
     SELECT @i,@c1,@c2 

     SELECT @[email protected]+1 
       ,@c1=NULL 
       ,@c2=NULL 

    END 

    DELETE FROM @Result 
    WHERE c1=c2 


RETURN 
END 
相关问题