problema de SQL, LEFT JOIN [..] IN ()
-
05-09-2019 - |
Pregunta
Este error SQL pequeña me está molestando. (?) No parece ser un problema con la consulta, sólo el ámbito de aplicación, ejemplos funcionan mejor:
SELECT ocp.*, oc.*, GROUP_CONCAT( u.username SEPARATOR ', ') AS `memjoined`
FROM gangs_ocs_process ocp, gangs_ocs oc
LEFT JOIN users u ON u.userid IN ( ocp.membersin )
WHERE ocp.ocid =1 AND ocp.gangid =1 AND oc.oc_name = ocp.crimename
GROUP BY ocp.ocid
LIMIT 0 , 30
Hay una columna (gangs_ocs_process.membersin), que tiene una lista de identificadores que se han unido (es decir, 1,2,5). Estoy tratando de obtener los nombres de usuario para cada uno de estos identificadores (de la tabla users
) de una sola vez.
El problema es LEFT JOIN users u ON u.userid IN ( ocp.membersin )
Si substitué 1,2,4
por ocp.membersin
(poniendo la lista literal en lugar del nombre de la columna), funciona bien. Devuelve una columna que tiene los nombres de usuario ( imagen ). Sin embargo, si lo dejo en el ocp.membersin, me sale este error:
#1054 - Unknown column 'ocp.membersin' in 'on clause'
Esta es la primera vez que he utilizado incluso en EN izquierda se une así que estoy un poco perdido.
Cualquier ayuda sería grande:)
Solución
No creo que "IN" va a trabajar para esta sintaxis. MySQL espera que IN sea algo parecido a un conjunto de datos, no una cadena delimitada. Creo que es necesario encontrar una manera de tomar membersin, ampliarlo en un conjunto de datos MySQL puede trabajar con (tal vez una tabla temporal), y unirse al respecto.
Otros consejos
Si ha delimitado cadenas en su mesa, usted tiene un problema de diseño en su base de datos. Añadir una nueva tabla para guardar estos valores.
¿Está seguro 'membersin' está en la tabla 'gangs_ocs_process', y no a la mesa '' gangs_ocs?
La razón por la que no se puede conseguir que funcione se debe a que primero es necesario obtener su base de datos normalizada. Usted nunca debería tener una lista de ID en una sola columna.
Después de tomar otra mirada, creo que su problema es tratar de agregar en el punto equivocado, así como la sintaxis IN y que debe agregarse en una sub consulta restringida por el contenido de la IN. No sé lo suficiente sobre su esquema para que este fuera de la caja correcta, pero quiero algo como esto. SomeKeyfield debe referirse de nuevo a gangs_ocs_process
SELECT ocp.*, oc.*, u.Memjoined
FROM gangs_ocs_process ocp, gangs_ocs oc
LEFT JOIN (Select SomeKeyField, GROUP_CONCAT( u.username SEPARATOR ', ') as memjoined
from users where userid in
(select membersin from gangs_ocs_process
where [whatever conditions] )
Group By SomeKeyField) u on ocp.SomeKeyField = u.SomeKeyField
WHERE ocp.ocid =1 AND ocp.gangid =1 AND oc.oc_name = ocp.crimename
GROUP BY ocp.ocid
LIMIT 0 , 30
Este es un mala manera para mantener la membresía.
Pero si usted todavía tiene que vivir con ello, puede utilizar la concordancia REGEXP
para la prueba de la membresía:
SELECT ocp.*, oc.*, GROUP_CONCAT( u.username SEPARATOR ', ') AS `memjoined`
FROM gangs_ocs_process ocp
LEFT JOIN users u ON (ocp.membersin RLIKE CONCAT('(^|,)[[:blank:]]?', userid, '[[:blank:]]?($|,)'))
JOIN gangs_ocs oc ON (ocp.ocid = 1 AND ocp.gangid = 1 AND oc.oc_name = ocp.crimename)
GROUP BY ocp.ocid
LIMIT 0 , 30