Ver Mensaje Individual
  #3 (permalink)  
Antiguo 31/07/2017, 13:53
leonardo_josue
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 4 meses
Puntos: 447
Respuesta: Como evitar un producto cartesiano en consulta entre 3 tablas

Hola heberthm:

No nos pones datos de ejemplo de tus tablas, pero mucho ojo, el que tu consulta muestre datos "repetidos" no necesariamente significa que se esté realizando un producto cartesiano...

lo primero que debes verificar es cuál es la cardinalidad entre tus tablas, si por ejemplo, tienes una relación 1 a 1, entonces una manera de verificar el si se está realizando un producto cartesiano es contando el número de registro que aparecen en la consulta final, el número de registros NO DEBE SER MAYOR AL NÚMERO DE REGISTROS EN CUALQUIERA DE TUS TABLAS. Checa este ejemplo:

Código SQL:
Ver original
  1. mysql> SELECT *
  2.     -> FROM tabla_1;
  3. +-----------+-------------+
  4. | id_tabla1 | descripcion |
  5. +-----------+-------------+
  6. |         1 | uno         |
  7. |         2 | dos         |
  8. |         3 | tres        |
  9. +-----------+-------------+
  10. 3 ROWS IN SET (0.00 sec)
  11.  
  12. mysql> SELECT *
  13.     -> FROM tabla_2;
  14. +-----------+-------------+
  15. | id_tabla2 | descripcion |
  16. +-----------+-------------+
  17. |         1 | one         |
  18. |         2 | two         |
  19. |         3 | three       |
  20. +-----------+-------------+
  21. 3 ROWS IN SET (0.00 sec)
  22.  
  23. mysql> SELECT * FROM tabla_1
  24.     -> INNER JOIN tabla_2 ON tabla_1.id_tabla1 = tabla_2.id_tabla2;
  25. +-----------+-------------+-----------+-------------+
  26. | id_tabla1 | descripcion | id_tabla2 | descripcion |
  27. +-----------+-------------+-----------+-------------+
  28. |         1 | uno         |         1 | one         |
  29. |         2 | dos         |         2 | two         |
  30. |         3 | tres        |         3 | three       |
  31. +-----------+-------------+-----------+-------------+
  32. 3 ROWS IN SET (0.00 sec)

Sin embargo, si tienes una relación 1 a muchos, puedes tener INFORMACIÓN "REPETIDA" pero esto no quiere decir que se esté haciendo un producto cartesiano, checa este ejemplo:

Código MySQL:
Ver original
  1. mysql> SELECT * FROM tabla_1;
  2. +-----------+-------------+
  3. | id_tabla1 | descripcion |
  4. +-----------+-------------+
  5. |         1 | uno         |
  6. |         2 | dos         |
  7. |         3 | tres        |
  8. +-----------+-------------+
  9. 3 rows in set (0.00 sec)
  10.  
  11. mysql> SELECT * FROM tabla_2;
  12. +-----------+-------------+
  13. | id_tabla2 | descripcion |
  14. +-----------+-------------+
  15. |         1 | one         |
  16. |         1 | un          |
  17. |         1 | eins        |
  18. |         2 | two         |
  19. |         2 | deux        |
  20. |         2 | zwei        |
  21. |         3 | three       |
  22. |         3 | trois       |
  23. |         3 | drei        |
  24. +-----------+-------------+
  25. 9 rows in set (0.00 sec)
  26.  
  27. mysql> SELECT * FROM tabla_1
  28.     -> INNER JOIN tabla_2 on tabla_1.id_tabla1 = tabla_2.id_tabla2;
  29. +-----------+-------------+-----------+-------------+
  30. | id_tabla1 | descripcion | id_tabla2 | descripcion |
  31. +-----------+-------------+-----------+-------------+
  32. |         1 | uno         |         1 | one         |
  33. |         1 | uno         |         1 | un          |
  34. |         1 | uno         |         1 | eins        |
  35. |         2 | dos         |         2 | two         |
  36. |         2 | dos         |         2 | deux        |
  37. |         2 | dos         |         2 | zwei        |
  38. |         3 | tres        |         3 | three       |
  39. |         3 | tres        |         3 | trois       |
  40. |         3 | tres        |         3 | drei        |
  41. +-----------+-------------+-----------+-------------+
  42. 9 rows in set (0.00 sec)

en este caso, las descripciones en español se están "repitiendo", pero esto no quiere decir que entre las tablas haya un PRODUCTO CARTESIANO, sino que esto es perfectamente normal debido a que hay una relación 1 a muchos entre las tablas...

entonces, ¿cuando ocurre un producto cartesiano? cuando un registro de una tabla se "combina" o se relaciona CON TODOS LOS REGISTROS DE OTRA TABLA... haya o no haya una relación entre ellos... es decir, algo así:

Código MySQL:
Ver original
  1. mysql> SELECT * FROM tabla_1
  2.     -> INNER JOIN tabla_2;
  3. +-----------+-------------+-----------+-------------+
  4. | id_tabla1 | descripcion | id_tabla2 | descripcion |
  5. +-----------+-------------+-----------+-------------+
  6. |         1 | uno         |         1 | one         |
  7. |         2 | dos         |         1 | one         |
  8. |         3 | tres        |         1 | one         |
  9. |         1 | uno         |         1 | un          |
  10. |         2 | dos         |         1 | un          |
  11. |         3 | tres        |         1 | un          |
  12. |         1 | uno         |         1 | eins        |
  13. |         2 | dos         |         1 | eins        |
  14. |         3 | tres        |         1 | eins        |
  15. |         1 | uno         |         2 | two         |
  16. |         2 | dos         |         2 | two         |
  17. |         3 | tres        |         2 | two         |
  18. |         1 | uno         |         2 | deux        |
  19. |         2 | dos         |         2 | deux        |
  20. |         3 | tres        |         2 | deux        |
  21. |         1 | uno         |         2 | zwei        |
  22. |         2 | dos         |         2 | zwei        |
  23. |         3 | tres        |         2 | zwei        |
  24. |         1 | uno         |         3 | three       |
  25. |         2 | dos         |         3 | three       |
  26. |         3 | tres        |         3 | three       |
  27. |         1 | uno         |         2 | trois       |
  28. |         2 | dos         |         2 | trois       |
  29. |         3 | tres        |         2 | trois       |
  30. |         1 | uno         |         3 | drei        |
  31. |         2 | dos         |         3 | drei        |
  32. |         3 | tres        |         3 | drei        |
  33. +-----------+-------------+-----------+-------------+
  34. 27 rows in set (0.00 sec)

esto SI ES UN PRODUCTO CARTESIANO.

Postea algunos datos de ejemplo de tus tablas para poder revisar.

Saludos
Leo.