No es exactamente que esté "jodido", sino que para darte una propuesta hay que depurar bastante la consulta que haces, y eso hay que explicártelo paso a paso para que se entienda bien.
Empecemos por ver tu consulta (un poco mejor escrita):
Código MySQL:
Ver original clientes
LEFT JOIN categorias CL
ON CL.cl_categoria_id
= CAT.c_id
LEFT JOIN usuarios US
ON CL.cl_merchandiser
= US.u_id
(SELECT *, IF(datos.d_semana
=$s
,'SI','NO') hay
WHERE DA.d_semana
='$s') DA
ON CL.cl_id
=DA.d_cliente
CL.cl_merchandiser='$elmercha'
Algunas de las cosas que se pueden considerar:
- El uso de LEFT JOIN indiscriminadamente como estás haciendo, sin que un resultado se relacione con otro (son lógicamente independientes), tiende a generar
productos cartesianos.
-
Si las relaciones son mandatorias, deberías usar INNER JOIN, y relacionar el resultado de un subconjunto al INNER JOIN siguiente.
- Hacer una subconsulta como tabla origen, pero poner una
condición binaria de esa misma por fuera (d_semana='$s'), no tiene sentido. Para eso la pones por
dentro de la subconsulta, donde será mas eficiente.
- Usas GROUP BY
sin funciones agregadas, lo que es ineficiente por un lado, y posiblemente innecesario por otra. SI el objetivo es que devuelva un sólo registro por cada cliente, lo primero que debes asegurarte es que no se estén generando
productos cartesianos por errores de JOIN, y no hacer un GROUP BY que al MySQL le insume mucho tiempo (y mucho más si hay P.C.).
- Por lo que dices el objeto final es obtener a los usuarios y verificar si para una semana dada existen o no datos relacionados. Para lograr eso
no se ve necesario el uso de ninguna otra tabla que no sean Usuarios y Datos. Si esto es porque estás "
refritando" una consulta diseñada para otro propósito a fin de lograr el resultado, eso es una pésima idea. Que dos conjuntos de resultados se
parezcan, no implica que se usen las
mismas consultas.
- Un JOIN no se usa con LIKE en el ON. Además, si lo que usas es el dato como lo planteas,
sin comodines, sin búsqueda de patrones, resulta igual que usar "=", por lo que no tiene ningún sentido.
- Resolver las consultas en bucles (loops) es una soberana tontería, propia de programadores, pero no es una solución práctica en Bases de Datos. En BBDD sólo se usan bucles como último recurso, o bien por requerimientos específicos del sistema.
Vamos a hacer una aproximación.
- Primero define qué campos de
necesitas realmente de cada tabla. Francamente no creo que necesites mostrar todos los datos de cada uno, especialmente porque el "*" te traerá información duplicada. No te olvides que una de las reglas de las consultas eficientes dice que no se debe pedir información que no sea estrictamente necesaria. Todo dato de más, son bytes basura en la transmisión de datos.
+ ¿Qué datos utilizarás de la tabla Clientes?
+ ¿Qué necesitas de Usuarios, Categoría, Zona y Canal?
+ ¿Para qué datos requieres la tabla Operadores?
- En segundo lugar, dinos cuáles son las relaciones
mandatorias, es decir, que relaciones deben existir si o si en esa base:
+ ¿Todos los clientes
tienen que tener categoría?
+ ¿Todos los clientes
tienen un canal?
+ ¿Todos los clientes
tienen una zona?
+ ¿A cada cliente le corresponde un
único usuario?
+ ¿A cada cliente le está asignado un
único operador?
Suponiendo que todos los JOIN fuesen mandatorios, la sentencia se debería parecer a esto:
Código MySQL:
Ver original clientes
INNER JOIN categorias CL
ON CL.cl_categoria_id
= CAT.c_id
(SELECT d_cliente
, IF(datos.d_semana
=$s
,'SI','NO') hay
WHERE DA.d_semana
='$s') DA
ON CL.cl_id
= DA.d_cliente
LEFT JOIN operadores OP
ON CL.cl_operador_id
= OP.o_id
CL.cl_merchandiser='$elmercha'
Por favor, contesta las preguntas de una forma precisa.
No nos des generalidades porque las generalidades no sirven para casos como el tuyo. Trata de ser concreto.
Saludos.