Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

limit en left join

Estas en el tema de limit en left join en el foro de Mysql en Foros del Web. hola gente traigo esto desde el foro de php donde consulte por este problema y me recomendaroa que me venta para el de mysql.. le ...
  #1 (permalink)  
Antiguo 15/03/2012, 12:20
 
Fecha de Ingreso: enero-2007
Mensajes: 285
Antigüedad: 17 años, 3 meses
Puntos: 21
Exclamación limit en left join

hola gente traigo esto desde el foro de php donde consulte por este problema y me recomendaroa que me venta para el de mysql.. le agradezco me den una mano.. saludos.


Cita:
Iniciado por marcusaurelio Ver Mensaje
hola gente como va? espero puedan iluminarme..

la idea es esta tengo una consulta que dice mas o menos asi..



Código PHP:

SELECT 
*, IF(datos.d_semana=$s,'SI','NO') as hay FROM (clientes 
left join categorias on clientes
.cl_categoria_id=categorias.c_id
left join canales on clientes.cl_canal_id=canales.ca_id 
left join zonas on clientes
.cl_prov_id=zonas.z_id 
left join operadores on clientes
.cl_operador_id LIKE operadores.o_id 
left join usuarios on clientes
.cl_merchandiser=usuarios.u_id 
left join datos on clientes
.cl_id=datos.d_cliente and datos.d_semana='$s' 
where clientes.cl_merchandiser='$elmercha'  $sql group by clientes.cl_id ORDER BY $orden 
el problema es en el join de la tabla datos.. por que esta tabla tiene muchiiiiisimos registros entonces al querer cargar la pagina se produce un time out...

la idea seria limitar el if.. para lo cual llegue a esta cosulta...

Código PHP:

SELECT 
FROM 
(clientes left join categorias on clientes.cl_categoria_id=categorias.c_id
left join canales on clientes.cl_canal_id=canales.ca_id 
left join zonas on clientes
.cl_prov_id=zonas.z_id 
left join operadores on clientes
.cl_operador_id LIKE operadores.o_id 
left join usuarios on clientes
.cl_merchandiser=usuarios.u_id 
left join 
(SELECT *, IF(datos.d_semana=$s,'SI','NO') as hay from datos limit 1) AS datos  on clientes.cl_id=datos.d_cliente and datos.d_semana='$s' 
where clientes.cl_merchandiser='$elmercha'  $sql group by clientes.cl_id ORDER BY $orden 
pero la misma no hace lo que quiero ya que.. si por ejemplo.. tendria que arrojarme 3 resultados solo me tira 1 por el limit..

alguien podria darme una mano con esto?
  #2 (permalink)  
Antiguo 16/03/2012, 03:32
Avatar de repara2  
Fecha de Ingreso: septiembre-2010
Ubicación: München
Mensajes: 2.445
Antigüedad: 13 años, 6 meses
Puntos: 331
Respuesta: limit en left join

Qué resultados esperas obtener??
__________________
Fere libenter homines, id quod volunt, credunt.
  #3 (permalink)  
Antiguo 16/03/2012, 08:14
 
Fecha de Ingreso: enero-2007
Mensajes: 285
Antigüedad: 17 años, 3 meses
Puntos: 21
Respuesta: limit en left join

necesito obtener un SI para cuando halla datos de la semana sumado al numero de usuario, y un no para cuando no lo halla.

siempre hablando de la tabla datos. el problema es que para eso recorre si o si todos los registros de esta tabla.. por cada vuelta del bucle.. son cerca de 150000 registros.. por cada vuelta de bucle.. se hace inmenso.
  #4 (permalink)  
Antiguo 23/03/2012, 21:07
 
Fecha de Ingreso: enero-2007
Mensajes: 285
Antigüedad: 17 años, 3 meses
Puntos: 21
Respuesta: limit en left join

uff ta jodido esto.. nadie tiene una idea de como seguir...?
  #5 (permalink)  
Antiguo 25/03/2012, 07:54
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: limit en left join

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
  1.     clientes
  2.     LEFT JOIN categorias CL ON CL.cl_categoria_id = CAT.c_id
  3.     LEFT JOIN canales CA ON CL.cl_canal_id = CA.ca_id
  4.     LEFT JOIN zonas ZO ON CL.cl_prov_id = ZO.z_id
  5.     LEFT JOIN operadores OP ON CL.cl_operador_id LIKE OP.o_id
  6.     LEFT JOIN usuarios US ON CL.cl_merchandiser = US.u_id
  7.     LEFT JOIN
  8.         (SELECT *, IF(datos.d_semana=$s,'SI','NO') hay
  9.         FROM datos
  10.         WHERE DA.d_semana='$s') DA  ON CL.cl_id=DA.d_cliente  
  11.     CL.cl_merchandiser='$elmercha'  
  12. GROUP BY clientes.cl_id
  13. ORDER BY $orden

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
  1.     clientes
  2.     INNER JOIN categorias CL ON CL.cl_categoria_id = CAT.c_id
  3.     INNER JOIN canales CA ON CL.cl_canal_id = CA.ca_id
  4.     INNER JOIN zonas ZO ON CL.cl_prov_id = ZO.z_id
  5.     INNER JOIN usuarios US ON CL.cl_merchandiser = US.u_id
  6.     INNER JOIN
  7.         (SELECT d_cliente, IF(datos.d_semana=$s,'SI','NO') hay
  8.         FROM datos
  9.         WHERE DA.d_semana='$s') DA  ON CL.cl_id = DA.d_cliente  
  10.     LEFT JOIN operadores OP ON CL.cl_operador_id = OP.o_id
  11.     CL.cl_merchandiser='$elmercha'  
  12. GROUP BY clientes.cl_id
  13. ORDER BY $orden

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.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Etiquetas: join, left, limit, php, registros, select, sql, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 05:28.