2012-03-16 56 views
7

Cuando comparo dos cadenas en SQL Server, hay dos maneras simples con = o LIKE.¿Cómo comparar si dos cadenas contienen las mismas palabras en T-SQL para SQL Server 2008?

que desea volver a definir la igualdad como:

Si dos cadenas contienen las mismas palabras - no importa en qué orden - son iguales, de lo contrario no lo son.

Por ejemplo:

  • 'my word' y 'word my' son iguales
  • 'my word' y 'aaamy word' no son

Cuál es la mejor solución sencilla para este problema?

+0

1) que importa mayúsculas y minúsculas? lo más probable es que no, pero pensé que debería preguntar. 2) ¿los elementos repetidos en un grupo que existen en el otro cuentan como una coincidencia o no? Es decir, ¿"mi palabra" es igual a "palabra mi palabra"? –

Respuesta

4

No creo que hay una solución simple para lo que intenta hacer en SQL Server. Mi primera idea sería crear una UDF CLR que:

  1. acepta dos cadenas
  2. rompe en dos matrices usando la función de división ""
  3. comparar el contenido de las dos matrices, volviendo cierto si ellos contienen los mismos elementos.

Si esta es una ruta que le gustaría ir, eche un vistazo a this article para comenzar a crear las UDF de CLR.

0

Puede agregar una columna precalculada en la tabla base que se evalúa en el desencadenador INSERT/UPDATE (o valor predeterminado UDF) que divide, ordena y luego concatena palabras de la columna original.

Luego use = para comparar estas columnas precalculadas.

1

El escenario es el siguiente. Usted querría usar un TVF para dividir la primera y la segunda cadena en el espacio y luego full join las dos tablas resultantes en los valores y si tiene nulos a la izquierda o a la derecha tiene desigualdad; de lo contrario, son iguales.

0

Hay una biblioteca llamada http://www.sqlsharp.com/ que contiene toda una gama de útiles funciones de cadena/matemáticas.

Tiene una función llamada String_CompareSplitValues ​​que hace exactamente lo que desea.

No estoy seguro de si está en la versión de comunidad o en la versión de pago.

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

Esto no es una respuesta para una consulta de una línea –

2

probar este ... La función StringSorter rompe cadenas en un espacio y luego ordena todas las palabras y pone la cadena de nuevo juntos en el orden de palabras ordenada.

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 

aquí es un caso de prueba sólo tratando a cabo la función:

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

que produjo los siguientes resultados:

brown dog fox jumped lazy over quick the the 

Luego de ejecutarlo desde una instrucción de selección utilizando sus cuerdas

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 

El primero en e muestra que son iguales, y el segundo no.

Esto debería hacer exactamente lo que está buscando con una función simple que utiliza un CTE recursivo para ordenar su cadena.

¡Disfrútalo!

1

una manera muy simple de hacer esto ... 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 
Cuestiones relacionadas