Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Qual é a alternativa de Find_in_set do mysql no Oracle


Não é uma alternativa exata para FIND_IN_SET , mas no seu caso de exemplo (onde você só precisa saber SE um valor está contido em um conjunto separado por vírgula) REGEX_COUNT com a regex '^([^,]+,)*your_value(,[^,]+)*$' vai caber.

Examine as seguintes consultas SQL (para Oracle)...

Exemplos com números


Pesquise o número 1 no conjunto:[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;

Retorna 1 corretamente

Pesquise o número 1 no conjunto:[111.222.333]. O INSTR não reportaria negativo neste caso.
SELECT
    CASE WHEN REGEXP_COUNT('111,222,333', '^([^,]+,)*1(,[^,]+)*$', 1, 'i') > 0
        THEN 1 ELSE 0
    END AS cnt
FROM DUAL;

Retorna 0 corretamente

Exemplos com strings


Procure por 'João' em um conjunto de nomes:
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;

Retorna 1 corretamente

Mas se você pesquisar pela letra 'a' , ele retornará corretamente zero (INSTR falharia novamente).
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;

Retorna 0 corretamente

Eu sei que esta pergunta foi respondida há muito tempo, mas ela está bem classificada nos resultados da pesquisa e provavelmente pode ajudar outras pessoas que procuram uma solução simples, mas mais correta do que o INSTR da Oracle função.

Expressões booleanas


Também é possível usar expressões booleanas, como OR ou E .

Um exemplo usando OR é o seguinte:
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;

Retorna 1 corretamente, pois encontrou "peter" (procure por "helen" ou "pedro" ).

Para E a abordagem é um pouco diferente (altera a expressão CASE em vez da 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;

A consulta acima procura por "john" E "pedro" . O E operação pode ser implementada facilmente duplicando o REGEXP_COUNT expressão no CASE sintaxe, porém em troca com uma pequena penalidade de desempenho.