Tema SQL
FIND_IN_SET() (MySQL / MariaDB)
Devuelve la posición (1-based) de una cadena dentro de una lista separada por comas, o 0 si no aparece. Pensada para columnas tipo SET o listas denormalizadas; no sustituye a una tabla relacional ni a JSON.
Descripción
FIND_IN_SET(str, lista_csv) compara el primer argumento con cada elemento de la segunda cadena separada por comas (sin espacios extra a menos que formen parte del valor). Es sensible a collation: comparaciones de cadenas siguen las reglas del conjunto de caracteres de la conexión. No uses esta función para buscar subcadenas arbitrarias dentro de texto libre: para eso existen LIKE, expresiones regulares o columnas JSON con índices. Si la lista crece o necesitas integridad referencial, normaliza a tabla puente. En consultas con índices, filtrar por FIND_IN_SET puede forzar escaneos completos; valora generar columna generada o tabla de desnormalización controlada.
Estructura general
Forma habitual de la sentencia: orden de cláusulas, qué parte filtra, agrupa o proyecta columnas, y qué devuelve el motor. Cópiala como plantilla y sustituye nombres por tus tablas reales.
FIND_IN_SET(str, lista_separada_por_comas)
Componentes
Cada componente tiene un papel concreto en la ejecución lógica de la sentencia. Léelos en orden: así entiendes qué puedes omitir, qué es obligatorio y qué expresiones son válidas en cada sitio según tu motor.
- Valor buscado
- Primera cadena; debe coincidir con un elemento completo de la lista, no con un prefijo.
- Lista CSV
- Segundo argumento: elementos separados por coma sin usar comas escapadas dentro de valores (limitación del modelo).
- Retorno
- Entero 1..N según posición, o 0 si no hay coincidencia; NULL si algún argumento es NULL.
- Rendimiento
- Evita usarla como único filtro en tablas muy grandes sin estrategia alternativa.
Ejemplos
Ejemplo 1
SELECT FIND_IN_SET('rojo', 'azul,rojo,verde') AS pos;
-- pos = 2
SELECT id, etiquetas
FROM articulos
WHERE FIND_IN_SET('sql', etiquetas) > 0;
Ejemplo 2
SELECT id FROM productos
WHERE FIND_IN_SET('rojo', etiquetas_colores) > 0
AND activo = 1;
Los ejemplos son ilustrativos. En producción usa consultas parametrizadas (prepared statements), revisa índices y aplica el principio de menor privilegio en cuentas de base de datos.