sql >> Base de Datos >  >> RDS >> Mysql

Valores separados por comas en la cláusula IN de MySQL

Sobre la base del ejemplo FIND_IN_SET() de @Jeremy Smith, puede hacerlo con una combinación para no tener que ejecutar una subconsulta.

SELECT * FROM table t
JOIN locations l ON FIND_IN_SET(t.e_ID, l.city) > 0
WHERE l.e_ID = ?

Se sabe que esto funciona muy mal, ya que tiene que hacer escaneos de tablas, evaluando la función FIND_IN_SET() para cada combinación de filas en table y locations . No puede hacer uso de un índice y no hay forma de mejorarlo.

Sé que dijo que está tratando de sacar lo mejor de un mal diseño de base de datos, pero debe comprender cuán drásticamente malo es esto.

Explicación:Suponga que le pidiera que buscara a todos en una guía telefónica cuya primera, segunda o última inicial es "J". No hay forma de que el orden ordenado del libro ayude en este caso, ya que tienes que escanear cada página de todos modos.

El LIKE solución dada por @fthiella tiene un problema similar con respecto al rendimiento. No se puede indexar.

También vea mi respuesta a ¿Es realmente tan malo almacenar una lista delimitada en una columna de base de datos? para otras trampas de esta forma de almacenar datos desnormalizados.

Si puede crear una tabla complementaria para almacenar un índice, puede asignar las ubicaciones a cada entrada en la lista de ciudades:

CREATE TABLE location2city (
 location INT,
 city INT,
 PRIMARY KEY (location, city)
); 

Suponiendo que tiene una tabla de búsqueda para todas las ciudades posibles (no solo las mencionadas en la table ) puede soportar la ineficiencia una vez para producir el mapeo:

INSERT INTO location2city (location, city)
  SELECT l.e_ID, c.e_ID FROM cities c JOIN locations l
  ON FIND_IN_SET(c.e_ID, l.city) > 0;

Ahora puede ejecutar una consulta mucho más eficiente para encontrar entradas en su table :

SELECT * FROM location2city l
JOIN table t ON t.e_ID = l.city
WHERE l.e_ID = ?;

Esto puede hacer uso de un índice. Ahora solo debe tener cuidado de que cualquier INSERCIÓN/ACTUALIZACIÓN/ELIMINACIÓN de filas en locations también inserta las filas de mapeo correspondientes en location2city .