Estoy trabajando en algo que muestra tiendas en una categoría específica, sin embargo, tengo un problema porque almaceno las categorías de una tienda como esta en un registro con la identificación de una categoría. "1,5,12". Ahora, el problema es que si quiero mostrar tiendas con categoría 2, "confunde" 12 con la categoría 2. Este es el SQL en este momento.

SELECT * FROM shops WHERE shop_cats LIKE '%".$sqlid."%' LIMIT 8

¿Hay alguna manera de dividir el registro "shop_cats" por una coma en SQL, para que compruebe el número completo? La única forma en que puedo pensar es en obtener todas las tiendas y hacerlo con PHP, pero no me gusta, ya que tomará demasiados recursos.

1
Anders 24 dic. 2016 a las 16:54

3 respuestas

La mejor respuesta

Esta es una muy, muy mala manera de almacenar categorías, por muchas razones:

  • Estás almacenando números como cadenas.
  • No puede declarar relaciones de clave externa adecuadas.
  • Una columna (normal) en una tabla debe tener solo un valor.
  • SQL tiene funciones de cadena pobres.
  • Las consultas resultantes no pueden aprovechar los índices.

La forma correcta de almacenar esta información en una base de datos es usar una tabla de unión, con una fila por tienda y por categoría.

A veces, estamos atrapados con las decisiones de diseño realmente malas de otras personas. Si este es su caso, puede usar FIND_IN_SET():

WHERE FIND_IN_SET($sqlid, shop_cats) > 0

Pero realmente deberías arreglar la estructura de datos.

4
Gordon Linoff 24 dic. 2016 a las 14:00

Si puede, la solución correcta debería ser normalizar la tabla, es decir, tener una fila separada por categoría, no con comas.

Si no puede, esto debería hacer el trabajo:

SELECT * FROM shops WHERE CONCAT(',' , shop_cats , ',') LIKE '%,".$sqlid.",%' LIMIT 8
3
Nir Levy 24 dic. 2016 a las 13:59

La tabla shops no sigue 1NF (primera forma normal), es decir; cada columna debe tener exactamente un valor. Para evitar eso, debe crear otra tabla llamada tabla dinámica que relacione dos tablas (o entidades). Pero para responder a su pregunta, la siguiente consulta SQL debería hacer el truco.

SELECT * FROM shops WHERE concat(',',shop_cats,',') LIKE '%,".$sqlid.",%' LIMIT 8
0
lucifer 24 dic. 2016 a las 15:29