Si je comprends bien votre besoin, cela pourrait être une solution.
Supposons que vous ayez un tableau comme celui-ci :
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
).
Cela pourrait être un moyen :
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'idée ici est de diviser votre chaîne d'entrée en plusieurs lignes, puis d'agréger les lignes résultantes dans l'ordre alphabétique, puis d'appliquer le même ordre sur les valeurs du tableau, puis de vérifier que les chaînes ordonnées sont égales.
Cette partie est utilisée pour diviser, ordonner et agréger les valeurs d'entrée, de sorte que le résultat soit une chaîne ordonnée :
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
donne :
ABCD
Cette partie sert à faire de même sur votre table :
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
donne :
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
La jointure entre ces résultats partiels est assez simple et vérifie simplement si une valeur (ordonnée) existe dans votre table qui correspond à la chaîne d'entrée (ordonnée).