Oracle
 sql >> Database >  >> RDS >> Oracle

Qual è l'alternativa a Find_in_set di mysql in Oracle

Non è un'alternativa esatta a FIND_IN_SET , ma nel tuo caso di esempio (dove devi solo sapere SE un valore è contenuto in un set separato da virgole) REGEX_COUNT con la regex '^([^,]+,)*your_value(,[^,]+)*$' si adatterà.

Esamina le seguenti query SQL (per Oracle)...

Esempi con numeri

Cerca il numero 1 nel set:[1,2,3,4,5,6,11,12,13]

SELECT
    CASE WHEN REGEXP_COUNT('1,2,3,4,5,6,11,12,13', '^([^,]+,)*1(,[^,]+)*$', 1, 'i') > 0
        THEN 1 ELSE 0
    END AS cnt
FROM DUAL;

Restituisce 1 correttamente

Cerca il numero 1 nell'insieme:[111.222.333]. INSTR non risulterebbe negativo in questo caso.

SELECT
    CASE WHEN REGEXP_COUNT('111,222,333', '^([^,]+,)*1(,[^,]+)*$', 1, 'i') > 0
        THEN 1 ELSE 0
    END AS cnt
FROM DUAL;

Restituisce 0 correttamente

Esempi con stringhe

Cerca 'John' in un insieme di nomi:

SELECT
    CASE WHEN REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*John(,[^,]+)*$', 1, 'i') > 0
        THEN 1 ELSE 0
    END as cnt
FROM DUAL;

Restituisce 1 correttamente

Ma se cerchi la lettera 'a' , restituirà correttamente zero (INSTR fallirebbe di nuovo).

SELECT
    CASE WHEN REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*a(,[^,]+)*$', 1, 'i') > 0
        THEN 1 ELSE 0
    END as cnt
FROM DUAL;

Restituisce 0 correttamente

So che a questa domanda è stata data risposta molto tempo fa, ma si posiziona bene nei risultati di ricerca e potrebbe probabilmente aiutare altri che cercano una soluzione semplice ma più corretta rispetto a INSTR di Oracle funzione.

Espressioni booleane

È anche possibile utilizzare espressioni booleane, come OR o AND .

Un esempio usando OR è il seguente:

SELECT
    CASE WHEN REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*(helen|peter)(,[^,]+)*$', 1, 'i') > 0
        THEN 1 ELSE 0
    END as cnt
FROM DUAL;

Restituisce 1 correttamente, poiché ha trovato "peter" (cerca "helen" o "pietro" ).

Per AND l'approccio è leggermente diverso (modifica l'espressione CASE invece della regex ):

SELECT
    CASE WHEN
            REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*john(,[^,]+)*$', 1, 'i') > 0 AND
            REGEXP_COUNT('john,peter,jim,kelly,laura,bill,tom,foo,bar', '^([^,]+,)*peter(,[^,]+)*$', 1, 'i') > 0
        THEN 1 ELSE 0
    END as cnt
FROM DUAL;

La query precedente cerca entrambi "john" E "Pietro" . Il AND l'operazione può essere implementata facilmente duplicando il REGEXP_COUNT espressione nel CASE sintassi, tuttavia in cambio di una piccola penalizzazione delle prestazioni.