比较SQL中具有不同顺序的两个不同字符串

时间:2014-11-07 20:38:02

标签: sql oracle

我在两个不同的表中有两列,想要比较字符串值。例如:

TABLE1.COLUMNA value = ABC, DEF, XYZ
TABLE2.COLUMNB value = ABC, XYZ, DEF

我想在两个字符串不相等时返回结果。在这种情况下,我不关心顺序我所关心的是这两个值是相等的。所以上面的例子中两个字符串相等。

这两个字符串不相等

TABLE1.COLUMNA value = ABC, DEF, XYZ
TABLE2.COLUMNB value = ABC, XYZ, LMN

仅供参考...我将此查询放入仅支持SQL查询的工具中。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:1)

这是一种存储列表的可怕,可怕的方式。但是,Oracle有一个叫做正则表达式的神奇功能,他们会允许你这样做。要了解它们,请尝试运行:

with t as (
      select '((a,)|(c,)|(b,)){3}' as pat from dual
     )
select pat, (case when regexp_like('a,b,c' ||',', pat) then 1 else 0 end)
from t;

返回true - 得出的结论是我们可以将字符串混淆,将其转换为正则表达式,以获得另一个字符串中元素的匹配。为了完全平等,我们希望双向进行比较。

所以,这里有一些代码可以解决你的问题:

with t as (
      select 'ABC,DEF,XYZ' as val1, 'ABC,XYZ,DEF' as val2 from dual union all
      select 'ABC,DEF,XYZ', 'ABC,XYZ,LMN' from dual
     )
select t.*,
       (case when regexp_like(val1 || ',', pat2||'{'||val2_len||'}') and
                  regexp_like(val2 || ',', pat1||'{'||val1_len||'}')
             then 1 else 0
        end) as comp 
from (select t.*,
             replace('((' || replace(val1 || ',', ',', ',)|(')||'))', '|())', ')') as pat1,
             replace('((' || replace(val2 || ',', ',', ',)|(')||'))', '|())', ')') as pat2,
             length(val1) - length(replace(val1, ',', '')) + 1 as val1_len,
             length(val2) - length(replace(val2, ',', '')) + 1 as val2_len
      from t
     ) t ;

如果列表中有重复值,则可能无效。但是,我将重复一遍,使用联结表或嵌套表是存储此信息的正确方法。不是字符串编码的列表。

答案 1 :(得分:0)

  1. 使用DELIMINATOR(,)分成3个简短的字符串' ABC' ' DEF' ' XYZ'
  2. 在不同的表格中存储这3个短串。
  3. 使用类似的东西
  4. SELECT *

    FROM(SELECT * FROM TABLE1

       EXCEPT
    
      SELECT * FROM TABL2)
    

    如果结果为空,则等于'

    使用此功能分裂

    CREATE FUNCTION [dbo].[fnSplitString] 
    ( 
        @string NVARCHAR(MAX), 
        @delimiter CHAR(1) 
    ) 
    RETURNS @output TABLE(splitdata NVARCHAR(MAX) 
    ) 
    BEGIN 
        DECLARE @start INT, @end INT 
        SELECT @start = 1, @end = CHARINDEX(@delimiter, @string) 
        WHILE @start < LEN(@string) + 1 BEGIN 
            IF @end = 0  
                SET @end = LEN(@string) + 1
    
            INSERT INTO @output (splitdata)  
            VALUES(SUBSTRING(@string, @start, @end - @start)) 
            SET @start = @end + 1 
            SET @end = CHARINDEX(@delimiter, @string, @start)
    
        END 
        RETURN 
    END
    
相关问题