【问题标题】:SQL Compare Characters in two stringsSQL比较两个字符串中的字符
【发布时间】:2018-10-30 21:31:48
【问题描述】:

如何比较 T-SQL (SQL Server) 中的两个字符串,以确定它们是否包含相同的字符,而它们的顺序不同。

例如:

一样

'671'
'716'

一样

'671'
'671'

不一样

'671'
'731'

【问题讨论】:

标签: sql-server string tsql compare character


【解决方案1】:

这真的很痛苦。一种方法是将字符分解,并以表格的形式进行比较:

with cte1 as (
      select left(v.s, 1) as l, stuff(v.s, 1, 1, '') as rest
      from (values ('671')) v(s)
      union all
      select left(rest, 1) as l, stuff(rest, 1, 1, '') as rest
      from cte1
      where rest <> ''
     ),
     cte2 as (
      select left(v.s, 1) as l, stuff(v.s, 1, 1, '') as rest
      from (values ('716')) v(s)
      union all
      select left(rest, 1) as l, stuff(rest, 1, 1, '') as rest
      from cte2
      where rest <> ''
     )
select (case when count(*) > 0 then 'NOT SAME' else 'SAME' end)
from (select l, sum(in1) as in1, sum(in2) as in2
      from ((select l, 1 as in1, 0 as in2 from cte1) union all
            (select l, 0 as in1, 1 as in2 from cte2) 
           ) i
      group by l
     ) l
where in1 <> in2

【讨论】:

    【解决方案2】:

    这是一个以两个字符串作为输入参数的函数。该函数将字符串分解为表变量并检查不同字符的计数是否相同以及两个表之间的连接是否返回相同的计数。

    因此它将 761 和 16767 视为相同的字符串。如果您希望字符串的长度相等,只需删除 distinct

    CREATE FUNCTION dbo.CompareStrings (@str1 VARCHAR(50), @str2 varchar(50))
    returns VARCHAR(50)
    BEGIN
      DECLARE @len1    INT,
              @len2    INT,
              @cnt1    INT =1,
              @cnt2    INT =1,
              @char1   VARCHAR(1)='',
              @char2   VARCHAR(1)='',
              @match bit = 0,
              @output VARCHAR(50)='Not same',
    
              @count1 int,
              @count2 int,
             @count_match int               
              declare @string1 table (alpha varchar(1))
              declare @string2 table (alpha varchar(1))
    
      SELECT @len1 = Len(@str1)
      WHILE @cnt1 <= @len1
        BEGIN
            SELECT @char1 = Substring(@str1, @cnt1, 1) 
            INSERT INTO @string1(alpha) values (@char1)
            SET @cnt1+=1
        END
    
    SELECT @len2 = Len(@str2)
      WHILE @cnt2 <= @len2
        BEGIN
            SELECT @char2 = Substring(@str2, @cnt2, 1) 
            INSERT INTO @string2(alpha) values (@char2)
            SET @cnt2+=1
        END
    
        select @count1 = count(distinct alpha) from @string1
        select @count2 = count(distinct alpha) from @string2
    
        select @count_match = count(distinct t1.alpha) from @string1 t1 inner 
    join @string2 t2 on t1.alpha = t2.alpha
    
        if (@count1 = @count2 AND @count1 = @count_match) 
            set  @match = 1
    
    
        if (@match =1)
            set @output = 'Same'
    
    
      RETURN @output
    END
    

    【讨论】:

      【解决方案3】:

      这是一种仅在您有 3 个字符作为样本时才有效的方法

      DECLARE @T TABLE
      (
        V1 VARCHAR(10),
        V2 VARCHAR(10)
      );
      
      INSERT INTO @T VALUES
      ('123', '312'),
      ('671', '176'),
      ('123', '341');
      
      SELECT CASE WHEN
             REPLACE(
                     REPLACE(
                             REPLACE(V1, SUBSTRING(V2, 1, 1), ''),
                             SUBSTRING(V2, 2, 1), ''
                             ),
                     SUBSTRING(V2, 3, 1), ''
                    ) = '' THEN 'SAME' ELSE 'NOT SAME' END Result
      FROM @T;
      

      返回:

      +----------+
      |  Result  |
      +----------+
      | SAME     |
      | SAME     |
      | NOT SAME |
      +----------+
      

      或者通过创建类似的函数

      CREATE FUNCTION IsSame 
      (
        @FStr VARCHAR(100), @SStr VARCHAR(100)
      ) 
      RETURNS VARCHAR(8)
      AS
      BEGIN
          DECLARE @I INT = 1;
          DECLARE @R VARCHAR(8) = 'NOT SAME';
          IF LEN(@FStr) <> LEN(@SStr)
              GOTO NotSame
                  ELSE
                      BEGIN
                          WHILE @I <= LEN(@SStr)
                              BEGIN
                                  SET @FStr = (SELECT REPLACE(@FStr, SUBSTRING(@SStr, @I, 1), ''));
                                  SET @I = @I + 1;
                              END
                      END
          IF @FStr = ''
              SET @R = 'SAME';    
          NotSame:
              RETURN @R;
      END
      GO
      

      那么你就可以把它当做

      SELECT dbo.IsSame('123', '312');
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多