Ver Mensaje Individual
  #8 (permalink)  
Antiguo 09/07/2012, 14:42
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: 16 años, 5 meses
Puntos: 2658
Respuesta: consulta relacionada con posibles registros inexistentes

Vamos a ver.
SI lo que quieres es el listado de todos aquellos productos que no figuran en ningún pedido registrado en la tabla VENTA, esa es la respuesta de esta consulta:
Código MySQL:
Ver original
  1.     P.ID,
  2.     P.Nombre,
  3.     IFNULL(V.Cantidad, 0) Cantidad
  4.     producto P
  5.     LEFT JOIN venta V ON P.ID = V.ID
  6.     P.Cantidad IS NULL;
O bien esta:

Código MySQL:
Ver original
  1.     P.ID,
  2.     P.Nombre,
  3.     IFNULL(V.Cantidad, 0) Cantidad
  4.     producto P
  5.     LEFT JOIN venta V ON P.ID = V.ID
  6.     P.ID IS NULL;
Explico:
1) NULL es un estado de indeterminación, no un dato, como ya te dije.
A nivel de consultas, si intento relacionar un valor A1 de la tabla A con otro valor A2 de la tabla B, y no existe relación, me muestra una relación inexistente.
Como una no existencia es en álgebra relacional, un conjunto vacío, pero "vacío" en datos es otra cosa, lo que devuelve es una indeterminación o estado de nulidad, denominado NULL (por cierto, el tema de los NULL abarca un capítulo entero en el manual de referencia, deberías leerlo).
Entonces, NULL me muestra precisamente lo que es una "no relación".

2) LEFT JOIN devuelve todos los registros de la primera tabla (a la izquierda del LEFT JOIN), tengan o no relación con los registros de la tabla derecha. Y como dijimos que una "no relación" es un NULL, devuelve NULL en todas las columnas de la tabla derecha que no se relacionen con las de la izquierda.

¿Se entiende?

Resumiendo:
SI lo que quieres es que te devuelva los resultados de un determinado producto, aunque las ventas sean cero:
Código MySQL:
Ver original
  1. mysql> SELECT
  2.     ->     P.ID,
  3.     ->     P.Nombre,
  4.     ->     IFNULL(V.CantidadVendida, 0) Cantidad
  5.     -> FROM
  6.     ->     producto P
  7.     ->     LEFT JOIN venta V ON P.ID = V.ID
  8.     -> WHERE
  9.     ->     P.ID = '2';
  10. +----+-----------+----------+
  11. | ID | Nombre    | Cantidad |
  12. +----+-----------+----------+
  13. |  2 | Milanesas |        0 |
  14. +----+-----------+----------+
  15. 1 row in set (0.00 sec)
Si quieres todos:
Código MySQL:
Ver original
  1. mysql> SELECT
  2.     ->     P.ID,
  3.     ->     P.Nombre,
  4.     ->     IFNULL(V.CantidadVendida, 0) Cantidad
  5.     -> FROM
  6.     ->     producto P
  7.     ->     LEFT JOIN venta V ON P.ID = V.ID
  8.     -> WHERE
  9.     ->     P.ID = '2' OR V.CantidadVendida IS NULL;
  10. +----+-----------+----------+
  11. | ID | Nombre    | Cantidad |
  12. +----+-----------+----------+
  13. |  2 | Milanesas |        0 |
  14. |  4 | Quesos    |        0 |
  15. +----+-----------+----------+
  16. 2 rows in set (0.03 sec)

Como puedes ver, sí se puede obtener datos aunque las ventas sean NULL. ¿Cuál es el secreto?
Simple:
- En el WHERE no puedes comparar valores contra los campos de la tabla derecha, sino contra la izquierda, para el caso de valores del campo usado como relación.
- Para determinar la "no relación" sólo debes preguntar si son NULL los campos de la tabla derecha, ya que los NULL de la izquierda no existen.
- Todo valor de la tabla derecha usado para ser comparado con algún parámetro, sólo aplicará con los registros que existan en la tabla derecha. Todos los demás son NULL.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Última edición por gnzsoloyo; 09/07/2012 a las 18:24