sql >> Base de Datos >  >> RDS >> Oracle

¿Cuál es la alternativa de Find_in_set de mysql en Oracle?

No es una alternativa exacta a MySQL FIND_IN_SET , pero en su caso de ejemplo (donde solo necesita saber SI un valor está contenido en un conjunto separado por comas) Oracle REGEX_COUNT con la expresión regular '^([^,]+,)*your_value(,[^,]+)*$' encajará.

Examine las siguientes consultas SQL (para Oracle)...

Ejemplos con números

Buscar el número 1 en el 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;

Devuelve 1 correctamente

Buscar el número 1 en el conjunto:[111,222,333]. INSTR no informaría negativo en este caso.

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

Devuelve 0 correctamente

Ejemplos con cadenas

Buscar 'John' en un conjunto de nombres:

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;

Devuelve 1 correctamente

Pero si busca la letra 'a' , devolverá correctamente cero (INSTR fallaría nuevamente).

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;

Devuelve 0 correctamente

Sé que esta pregunta se respondió hace mucho tiempo, pero se clasifica bien en los resultados de búsqueda y probablemente podría ayudar a otros que buscan una solución sencilla pero más correcta que el INSTR de Oracle. función.

Expresiones booleanas

También es posible utilizar expresiones booleanas, como OR o AND .

Un ejemplo usando OR es el siguiente:

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;

Devuelve 1 correctamente, ya que encontró "peter" (busque "helen" o "pedro" ).

Para AND el enfoque es un poco diferente (modifica la expresión CASE en lugar de 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 consulta anterior busca tanto "john" Y "pedro" . El AND La operación se puede implementar fácilmente duplicando el REGEXP_COUNT expresión en el CASE sintaxis, sin embargo, a cambio de una pequeña penalización de rendimiento.