比较两个逗号分隔的字符串

时间:2016-01-29 06:34:52

标签: sql oracle

我有2个字符串str1'abc,def,ghi'str2'tyu,abc,fgh'

我想使用分隔符,比较这两个字符串。现在因为2个字符串有abc,所以它应该返回true。我想在Oracle SQL中使用一个可以执行此操作的函数。

3 个答案:

答案 0 :(得分:2)

看起来很复杂,但它只是一些帮助函数将列表拆分为单独的值(包含在表类型中),然后是一个非常简单的函数来测试两个集合的交集。

Oracle安装程序

CREATE TYPE VARCHAR2s_Table AS TABLE OF VARCHAR2(4000);

CREATE FUNCTION regexp_escape(
  expression VARCHAR2
) RETURN VARCHAR2 DETERMINISTIC
AS
BEGIN
  RETURN REGEXP_REPLACE( expression, '([$^[()+*?{\|])', '\\\1', 1, 0, 'c' );
END;
/

CREATE FUNCTION splitList(
  list  VARCHAR2,
  delim VARCHAR2 := ','
) RETURN VARCHAR2s_Table DETERMINISTIC
AS
  pattern   VARCHAR2(256);
  len       BINARY_INTEGER;
  t_items   VARCHAR2s_Table := VARCHAR2s_Table();
BEGIN
  IF list IS NULL THEN
    NULL;
  ELSIF delim IS NULL THEN
    t_items.EXTEND( LENGTH( list ) );
    FOR i IN 1 .. LENGTH( list ) LOOP
      t_items(i) := SUBSTR( list, i, 1 );
    END LOOP;
  ELSE
    pattern   := '(.*?)($|' || REGEXP_ESCAPE( delim ) || ')';
    len       := REGEXP_COUNT( list, pattern ) - 1;
    t_items.EXTEND( len );
    IF len = 1 THEN
      t_items(1) := list;
    ELSE
      FOR i IN 1 .. len LOOP
        t_items(i) := REGEXP_SUBSTR( list, pattern, 1, i, NULL, 1 );
      END LOOP;
    END IF;
  END IF;
  RETURN t_items;
END;
/

CREATE FUNCTION check_list_intersect(
  list1 VARCHAR2,
  list2 VARCHAR2
) RETURN NUMBER DETERMINISTIC
AS
BEGIN
  IF splitList( list1 ) MULTISET INTERSECT splitList( list2 ) IS EMPTY THEN
    RETURN 0;
  ELSE
    RETURN 1;
  END IF;
END;
/

查询1

SELECT check_list_intersect( 'abc,def,ghi', 'abc' ) AS matches
FROM   DUAL;

<强>结果:

 MATCHES
---------
       1

查询2

SELECT check_list_intersect( 'abc,def,ghi', 'abcd' ) AS matches
FROM   DUAL;

<强>结果:

 MATCHES
---------
       0

答案 1 :(得分:1)

以下将会成功。

with temp as  (
       select 1 strid, 'abc,def,ghi' Error  from dual
       union all
       select 2, 'tyu,abc,fgh'  from dual
     )
select str 
from (
     SELECT  strid, trim(regexp_substr(str, '[^,]+', 1, level)) str
     FROM (SELECT strid, Error str FROM temp) t
     CONNECT BY instr(str, ',', 1, level - 1) > 0 
     )
group by str 
having count(distinct strid) > 1;

答案 2 :(得分:0)

警告:此答案不完全正确。(请参阅评论。)

从dcieslak回答开始(用regexp分割csv),主题的变体将是:

create or replace function check_string_intersec(str1 varchar2, str2 varchar2) return number 
is
begin
   for k in (SELECT  trim(regexp_substr(str1, '[^,]+', 1, level)) item
             FROM dual
             CONNECT BY instr(str1, ',', 1, level - 1) > 0 
             )
   loop
       if instr(str2, k.item,1) > 0 then return 1; end if;
   end loop;
   return 0;
end;

这会拆分第一个字符串并搜索第二个字符串中的每个项目。