Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Abfragetabelle mit unterschiedlichen Variablenlisten mit like

Wenn ich Ihr Bedürfnis gut verstehe, könnte dies ein Weg sein.

Angenommen, Sie haben eine Tabelle wie diese:

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
).

Dies könnte ein Weg sein:

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)

Die Idee hier ist, Ihre Eingabezeichenfolge in viele Zeilen aufzuteilen und dann die resultierenden Zeilen in alphabetischer Reihenfolge zusammenzufassen, dann die gleiche Reihenfolge auf die Werte in der Tabelle anzuwenden und dann zu überprüfen, ob die geordneten Zeichenfolgen gleich sind.

Dieser Teil wird verwendet, um die Eingabewerte aufzuteilen, zu ordnen und zusammenzufassen, sodass das Ergebnis ein geordneter String ist:

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

ergibt:

ABCD

Dieser Teil wird verwendet, um dasselbe auf Ihrem Tisch zu tun:

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  

ergibt:

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

Die Verbindung zwischen diesen Teilergebnissen ist recht einfach und prüft einfach, ob ein (geordneter) Wert in Ihrer Tabelle existiert, der der (geordneten) Eingabezeichenfolge entspricht.