Se capisco bene la tua esigenza, questo potrebbe essere un modo.
Supponiamo che tu abbia una tabella come questa:
create table yourTable(setid, codes, messagedescr) as (
select 1, 'A, B, C, D', 'You can login' from dual union all
select 2, 'B, C, D' , 'You can login for one day' from dual union all
select 3, 'A, C, E' , 'You can login but update your profile' from dual union all
select 4, 'B, C, E, F', 'You cannot login' from dual
).
Questo potrebbe essere un modo:
with inputData(codes) as (
select listagg(trim (regexp_substr(input_codes, '[^,]+', 1, level))) within group ( order by trim (regexp_substr(input_codes, '[^,]+', 1, level)))
from ( select 'A, D, C, B' as input_codes from dual ) /* the input string */
CONNECT BY instr(input_codes, ',', 1, level - 1) > 0
)
select *
from inputData
inner join (
select listagg(trim (regexp_substr(codes, '[^,]+', 1, level)))
within group ( order by trim (regexp_substr(codes, '[^,]+', 1, level))) as codes,
messagedescr
from yourTable
CONNECT BY instr(codes, ',', 1, level - 1) > 0
and prior setId = setId
and prior sys_guid() is not null
group by setId, messagedescr
)
using (codes)
L'idea qui è di dividere la stringa di input in più righe, quindi aggregare le righe risultanti in ordine alfabetico, quindi applicare lo stesso ordine ai valori nella tabella e quindi verificare che le stringhe ordinate siano uguali.
Questa parte viene utilizzata per dividere, ordinare e aggregare i valori di input, in modo che il risultato sia una stringa ordinata:
select listagg(trim (regexp_substr(input_codes, '[^,]+', 1, level))) within group ( order by trim (regexp_substr(input_codes, '[^,]+', 1, level)))
from ( select 'A, D, C, B' as input_codes from dual ) /* the input string */
CONNECT BY instr(input_codes, ',', 1, level - 1) > 0
dà:
ABCD
Questa parte viene utilizzata per fare lo stesso sul tuo tavolo:
select listagg(trim (regexp_substr(codes, '[^,]+', 1, level)))
within group ( order by trim (regexp_substr(codes, '[^,]+', 1, level))) as codes,
messagedescr
from yourTable
CONNECT BY instr(codes, ',', 1, level - 1) > 0
and prior setId = setId
and prior sys_guid() is not null
group by setId, messagedescr
dà:
CODES MESSAGEDESCR
---------- -------------------------------------
ABCD You can login
BCD You can login for one day
ACE You can login but update your profile
BCEF You cannot login
Il join tra questi risultati parziali è abbastanza semplice e controlla semplicemente se nella tabella esiste un valore (ordinato) che corrisponde alla stringa di input (ordinata).