Сравнивать строки, разделенные запятыми, если в них есть одинаковое число

У меня есть две строки, первая выглядит так: 24,36,78,98. второй такой: 25,36,88,98

Теперь я хочу сравнить две строки в sql и вернуть только те числа, которые одинаковы в каждой строке.

Возможно ли это в sql или мне нужно написать свою собственную функцию, например PL/SQL?

Я погуглил, но не нашел ответов на этот вопрос.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
0
65
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Это можно сделать в sql или pl/sql в зависимости от ваших потребностей:

plsql

Если в вашей базе данных установлен Oracle APEX, у вас есть APEX_STRING API, который вы можете использовать для преобразования строки в массив. Затем используйте оператор MULTISET, чтобы получить пересечение значений:

set serveroutput on size 999999
clear screen
DECLARE
  l_string1 VARCHAR2(100) :=  '24,36,78,98';
  l_string2 VARCHAR2(100) :=  '25,36,88,98';
  l_string_intersect VARCHAR2(100);
  l_string1_arr apex_t_varchar2;
  l_string2_arr apex_t_varchar2;
  l_intersect_arr  apex_t_varchar2;
BEGIN 
  l_string1_arr :=  apex_string.split(l_string1,',');
  l_string2_arr :=  apex_string.split(l_string2,',');
  l_intersect_arr := l_string1_arr MULTISET INTERSECT l_string2_arr;
  l_string_intersect := apex_string.join(l_intersect_arr,',');
  dbms_output.put_line('intersect values: '||l_string_intersect);
END;
/

PL/SQL procedure successfully completed.



intersect values: 36,98

Без APEX, и если вам все еще нужен pl/sql, используйте технику sql для разделения (см. ниже) и используйте оператор MULTISET для получения пересечения.

sql

для sql, посмотрите этот блог о различных методах разделения строки, разделенной запятыми, на значения.

Вот пример того, как это сделать, используя технику, описанную в блоге выше:

with 
string1 as (
  select '24,36,78,98' str from dual
),
string2 as (
  select '25,36,88,98' str from dual
), 
string1_tab as (
  select regexp_substr (
           str,
           '[^,]+',
           1,
           level
         ) value
  from   string1
  connect by level <= 
    length ( str ) - length ( replace ( str, ',' ) ) + 1
),
string2_tab as (
  select regexp_substr (
           str,
           '[^,]+',
           1,
           level
         ) value
  from   string2
  connect by level <= 
    length ( str ) - length ( replace ( str, ',' ) ) + 1
)
select * from string1_tab
INTERSECT
select * from string2_tab
;

Еще один вариант (выглядит довольно просто), который разбивает строку на строки, чтобы можно было применить оператор набора пересечений.

Образец данных:

SQL> with test (col1, col2) as
  2    (select '24,36,78,98', '25,36,88,98' from dual)

Запрос начинается здесь:

  3  select regexp_substr(col1, '[^,]+', 1, level) val
  4    from test
  5    connect by level <= regexp_count(col1, ',') + 1
  6  intersect
  7  select regexp_substr(col2, '[^,]+', 1, level) val
  8    from test
  9    connect by level <= regexp_count(col2, ',') + 1;

VAL
-----------
36
98

SQL>

Еще один с XQuery:

with data(a,b) as (
    select '24,36,78,98', '25,36,88,98' from dual
)
select t.* from 
data d,
xmltable( 
  'for $i in (ora:tokenize($X,",")), $j in (ora:tokenize($Y,",")) where ($i = $j) return $i'
  passing a as "X", b as "Y"
  columns val number path '.'
) t
;

Ваше воображение — единственный предел для изобретения других... С 23c вы даже можете использовать MLE для работы с функцией Javascript в массивах JSON:

export function intersect(arr1string, arr2string) {
    let arr1 = eval(arr1string == null? [] : arr1string);
    let arr2 = eval(arr2string == null? [] : arr2string);
    return arr1.filter(n => arr2.includes(n));
}

Другие вопросы по теме