2016-01-29 2 views
1

У меня есть 2 строки str1: 'abc,def,ghi' и str2: 'tyu,abc,fgh'.Сравнение двух строк с разделителями-запятыми

Я хочу сравнить эти две строки, используя разделитель ,. Теперь, поскольку 2 строки имеют abc, он должен возвращать true. Я хочу функцию в Oracle SQL, которая может выполнять эту операцию.

+0

Вы можете разделить строки с разделителями в виде строк, а затем сравнить. См. [** Разделите строки с разделителями-запятыми в таблице в Oracle **] (http://lalitkumarb.com/2015/03/04/split-comma-delimited-strings-in-a-table-in-oracle/) –

ответ

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; 
+0

это приятно, что больше sql-istic, используя SQL-движок для сравнения вещей. –

0

Предупреждение: Этот ответ не вполне правильно. (см. Комментарии)

Начиная с dcieslak ответа (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; 

Это разбивает первую строку и поиск для каждого элемента во второй строке ,

+0

есть ли какая-либо функция predefinrd, которая может выполнить это действие? – Nancy

+0

почти наверняка нет. Он должен быть реализован в библиотеке. –

+0

'check_string_intersec ('abc, def, ghi', 'abcd')' Вторая строка не имеет элемента 'abc', поэтому функция должна возвращать' 0', но 'INSTR' найдет соответствие. – MT0

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 

Query 2:

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

Результаты:

MATCHES 
--------- 
     0 
+0

Это то, что я называю «полным решением pl/sql». Отлично. –

Смежные вопросы