2012-03-16 18 views
7

Quando si confrontano due stringhe in SQL Server, ci sono un paio di modi semplici con = o LIKE.Come confrontare se due stringhe contengono le stesse parole in T-SQL per SQL Server 2008?

Voglio ridefinire l'uguaglianza come:

Se due stringhe contengono le stesse parole - non importa in quale ordine - sono uguali, altrimenti non lo sono.

Ad esempio:

  • 'my word' e 'word my' sono uguali
  • 'my word' e 'aaamy word' non sono

Qual è la migliore soluzione semplice per questo problema?

+0

1) che conta maiuscole e minuscole? molto probabilmente non ho pensato che avrei dovuto chiedere. 2) fare gli elementi ripetuti in un gruppo che esistono nell'altro conteggio come corrispondenza o no? Che significa "la mia parola" equivale a "parola mia parola"? –

risposta

4

Non credo che ci sia una soluzione semplice per ciò che stai cercando di fare in SQL Server. Il mio primo pensiero sarebbe quello di creare un CLR UDF che:

  1. accetta due stringhe
  2. li rompe in due array usando la funzione split su ""
  3. confrontare il contenuto di due array, restituendo vero se contengono gli stessi elementi.

Se si tratta di un percorso che si desidera visitare, dare un'occhiata a this article per iniziare a creare UDF CLR.

0

È possibile aggiungere una colonna precalcata nella tabella di base valutata nel trigger INSERT/UPDATE (o predefinito UDF) che suddivide, ordina e quindi concatena le parole dalla colonna originale.

Quindi utilizzare = per confrontare queste colonne precalcolate.

1

Lo scenario è il seguente. Dovresti usare un TVF per dividere la prima e la seconda stringa nello spazio e poi full join le due tabelle risultanti sui valori e se hai valori nulli a sinistra o a destra hai disuguaglianza altrimenti sono uguali.

0

C'è una libreria chiamata http://www.sqlsharp.com/ che contiene un'intera gamma di utili funzioni stringa/matematica.

Ha una funzione denominata String_CompareSplitValues ​​che esegue esattamente ciò che si desidera.

Non sono sicuro se è nella versione di comunità o nella versione a pagamento.

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

Questa non è una risposta per una query su una riga –

2

Provare questo ... La funzione StringSorter interrompe le stringhe su uno spazio e quindi ordina tutte le parole e rimette la stringa di nuovo insieme in ordine di parole ordinato.

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 

Questo vuole essere un banco di prova solo cercando la funzione:

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

che ha prodotto questi risultati:

brown dog fox jumped lazy over quick the the 

Poi, per eseguirlo da una dichiarazione prescelta utilizzando le corde

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 

Il primo in e mostra che sono uguali, e il secondo no.

Questo dovrebbe fare esattamente quello che stai cercando con una semplice funzione che utilizza un CTE ricorsivo per ordinare la stringa.

Divertiti!

1

un modo molto semplice per fare questo ... 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 
Problemi correlati