SQL Сравнить символы в двух строках - PullRequest
0 голосов
/ 31 октября 2018

Как можно сравнить две строки в T-SQL (SQL Server), чтобы определить, содержат ли они одни и те же символы, но не в том же порядке.

Например:

SAME

'671'
'716'

SAME

'671'
'671'

НЕ ЖЕ

'671'
'731'

Ответы [ 3 ]

0 голосов
/ 31 октября 2018

Этот метод работает, только если у вас есть 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');
0 голосов
/ 31 октября 2018

Вот функция с двумя строками в качестве входных параметров. Функция разбивает строки на табличные переменные и проверяет, одинаково ли количество различных символов и совпадает ли объединение двух таблиц.

Таким образом, он рассматривает 761 и 16767 как одинаковые строки. Если вы хотите, чтобы строки были равны по длине, просто удалите отличные

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
0 голосов
/ 31 октября 2018

Это действительно больно. Один из способов - взорвать символы и сравнить их в виде таблиц:

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
...