Ver Mensaje Individual
  #6 (permalink)  
Antiguo 25/07/2016, 05:54
Avatar de gnzsoloyo
gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: Procedimiento almacenado - ventajas

El LEFT JOIN es una de las fuentes de mayor confusión y bajas de performance, además de causar errores de datos cuando se usa con descuido.
Tienes que tener muy en cuenta que LEFT JOIN devuelve TODO lo que está en la tabla a su izquierda tenga O NO TENGA relación con lo que está en la tabla a su derecha. Eso tiene el potencial de levantar registros innecesarios luego, lo que reduce la performance general de la consulta. Y esto sin contar con la posibilidad de generar relaciones en estrella, las que causan productos cartesianos...
A diferencia de las matemáticas, el orden de los factores (tablas) SI modifica el producto (RESULTADO de la consulta). No es lo mismo poner las tablas en un orden que en el otro.
Para usar tu ejemplo, si pones a la izquierda las ventas y a la derecha los clientes, la query te devolverá todas las ventas de los clientes que hayan comprado, pero no te devolverá clientes que no posean compras del tipo buscado, lo que es una diferencia notoria para el reporte que planteas en este caso.
En los hechos ese LEFT JOIN opera como un INNER JOIN, solo que invoca el algoritmo equivocado. No es igual buscar con un INNER que con un LEFT. No para el DBMS.

¿Se va entendiendo la forna de analizar las cosas?

En tu caso, si lo que quieres es el listado completo de clientes que efectivamente hayan realizado una compra, no debes usar LEFT JOIN, asi como tampoco usarlo en la busqueda de los datos del cliente, o el producto. Esas son relaciones mandatorias, por lo que corresponde usar INNER JOIN.
Adicionalmente, es mejor poner las tablas en el mismo orden de los datos que se desean encontrar

Algo como:

Código MySQL:
Ver original
  1. SELECT comercial ,
  2.        ID_Cliente,
  3.        Cliente,
  4.        Ciudad,
  5.        Provincia,
  6.        Sum(cantidad1 + cantidad2)  AS CantidadTotal,
  7.        Count(DISTINCT( idventas )) AS Visitas
  8. FROM clientes cli
  9.     INNER JOIN direccionClientes cdir on cdir.idDireccion = cli.idcliente
  10.     LEFT JOIN ventas v ON  cli.idcliente = v.idcliente
  11.     INNER JOIN mov ON  v.idventas = mov.idmov
  12.     INNER JOIN listado inv on inv.id = v.idventas
  13.     INNER JOIN productos p on p.idproducto = inv.idproducto
  14.     INNER JOIN comerciales u on u.id = mov.idcomercial
  15. WHERE p.categoria = 'Zapatos'
  16. GROUP BY cli.idcliente
  17. ORDER BY comercial

Si solo quieres los clientes que compraron zapatos, entonces cambia el LEFT por el INNER en el segundo caso.

Nota: Esa query puede devolver lo mismo que la anterior, si interpreté todo correctamente,
En todo caso hay que verificar el funcionamiento genera de la performance.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)