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

Consulta multitabla con doble clave foránea

Estas en el tema de Consulta multitabla con doble clave foránea en el foro de Mysql en Foros del Web. Hola, Tengo una tabla que tiene Juego; idjuego id_player1 id_player2 jugadores; id_player usuario id_nivel niveles id_nivel nivel y lo que quiero es listar de esta ...
  #1 (permalink)  
Antiguo 11/10/2011, 18:00
Avatar de latinpower  
Fecha de Ingreso: septiembre-2010
Ubicación: Canelones
Mensajes: 116
Antigüedad: 13 años, 7 meses
Puntos: 10
Consulta multitabla con doble clave foránea

Hola,

Tengo una tabla que tiene

Juego;

idjuego
id_player1
id_player2

jugadores;
id_player
usuario
id_nivel

niveles
id_nivel
nivel

y lo que quiero es listar de esta forma

idjuego:
usuario1
usuario2
nivel-usuario1
nivel-usuario2

El problema que tengo es al poner la condición doble, es decir yo tengo, WHERE jugadores.idjugadores = juego.id_player1 AND jugadores.idjugadores = juego.id_player2

Pero mysql me toma como que id_player1 y player2 deben tener el mismo id, y no sé como arreglarlo. Estuve viendo el Join pero no estoy seguro de si me serviría.

Gracias.
  #2 (permalink)  
Antiguo 12/10/2011, 08:22
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: Consulta multitabla con doble clave foránea

Hola latinpower:

Siempre es mejor opción utilizar JOIN'S cuando tienes más de una tabla en tu consulta:

En lugar de poner esto:
Código:
FROM Tabla1, Tabla2 
WHERE Tabla1.Campo = Tabla2.Campo
Es mejor poner esto:

Código:
FROM Tabla1 INNER JOIN Tabla2
ON Tabla1.Campo = Tabla2.Campo
Ahora bien, con respecto a tu problema, es necesario "duplicar" tu tabla jugadores en la consulta, utilizando Alias, para hacer un JOIN con cada uno de los ID's. Tal y como estás poniendo tu consulta sería como pedirle a un arbol de manzanas que dé manzanas pero que también dé naranjas, cosa que no es posible.

Sería más o menos así:

Código MySQL:
Ver original
  1. mysql> create table jugadores (id_player int, nombre varchar(10));
  2. Query OK, 0 rows affected (0.17 sec)
  3.  
  4. mysql> insert into jugadores values (1, 'uno'), (2, 'dos'), (3, 'tres');
  5. Query OK, 3 rows affected (0.12 sec)
  6. Records: 3  Duplicates: 0  Warnings: 0
  7.  
  8. mysql> select * from jugadores;
  9. +-----------+--------+
  10. | id_player | nombre |
  11. +-----------+--------+
  12. |         1 | uno    |
  13. |         2 | dos    |
  14. |         3 | tres   |
  15. +-----------+--------+
  16. 3 rows in set (0.17 sec)
  17.  
  18. mysql> create table juego (id_game int, id_player_1 int, id_player_2 int);
  19. Query OK, 0 rows affected (0.11 sec)
  20.  
  21. mysql> insert into juego values (1, 1, 2), (2, 1, 3), (3, 2, 3);
  22. Query OK, 3 rows affected (0.04 sec)
  23. Records: 3  Duplicates: 0  Warnings: 0
  24.  
  25. mysql> select * from juego;
  26. +---------+-------------+-------------+
  27. | id_game | id_player_1 | id_player_2 |
  28. +---------+-------------+-------------+
  29. |       1 |           1 |           2 |
  30. |       2 |           1 |           3 |
  31. |       3 |           2 |           3 |
  32. +---------+-------------+-------------+
  33. 3 rows in set (0.00 sec)
  34.  
  35. mysql> select J.id_game, J1.nombre, J2.nombre
  36.     -> from juego J
  37.     -> inner join jugadores J1 on J.id_player_1 = J1.id_player
  38.     -> inner join jugadores J2 on J.id_player_2 = J2.id_player;
  39. +---------+--------+--------+
  40. | id_game | nombre | nombre |
  41. +---------+--------+--------+
  42. |       1 | uno    | dos    |
  43. |       2 | uno    | tres   |
  44. |       3 | dos    | tres   |
  45. +---------+--------+--------+
  46. 3 rows in set (0.06 sec)

Dale un vistazo y si continuas con problemas lo comentas en el foro.

Saludos
Leo.
  #3 (permalink)  
Antiguo 12/10/2011, 20:54
Avatar de latinpower  
Fecha de Ingreso: septiembre-2010
Ubicación: Canelones
Mensajes: 116
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Consulta multitabla con doble clave foránea

Muchas gracias, me quedo muy bien.

Solo me queda una duda, por qué me habías dicho que era mejor join que que where?

Gracias.
  #4 (permalink)  
Antiguo 13/10/2011, 08:47
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: Consulta multitabla con doble clave foránea

hola latinpower:

La razón principal para el uso de JOIN's en lugar de WHERE son los tiempos de respuesta: aunque el resultado de las consultas es el mismo las rutinas implementadas en los JOIN'S están optimizadas, de tal suerte que en consultas con tablas muy grandes los tiempos de respuesta pueden ser bastante diferentes.

Por experiencia propia te comento que en el trabajo obtuvimos mejoras en tiempos de respuesta bastante considerables simplemente cambiando los joins. Es posible que si tus tablas no son muy grandes no veas cambios significativos en los tiempos, pero podrías hacer la prueba de cualquier manera.

Ademas en lo particular, pienso que las consultas quedan más legibles o "entendibles" utilizando JOINS ya que separas perfectamente los criterios que utilizas para unir las tablas y las condiciones normales. Te pongo dos ejemplos.

Código MySQL:
Ver original
  1. select T1.campo, T2.campo, T3.campo, T4.campo, Tabla5.Campo
  2. from tabla1 T1, Tabla2 T2, Tabla3 T3, Tabla4 T4, Tabla5 T5
  3. t1.campo = T2.campo and
  4. t1.campo2 = 1 and
  5. t1.campo = t3.campo and
  6. t2.campo2 = 'algo' and
  7. t1.campo = T4.campo and
  8. T3.campo3 > 10 and
  9. T4.campo4 not in (1,2,3) and
  10. T5.campo between 100 and 200
  11.  
  12. select T1.campo, T2.campo, T3.campo, T4.campo, Tabla5.Campo
  13. from tabla1 T1
  14. inner join Tabla2 T2 on t1.campo = T2.campo
  15. inner join Tabla3 T3 on t1.campo = t3.campo
  16. inner join Tabla4 T4 on t1.campo = T4.campo
  17. inner join Tabla5 T5 on T1.campo = T5.campo
  18. t1.campo2 = 1 and
  19. t2.campo2 = 'algo' and
  20. T3.campo3 > 10 and
  21. T4.campo4 not in (1, 2, 3)
  22. T5.campo between 100 and 200

en el primer caso, al mezclar tanto las condiciones de unión como las condiciones de filtrado en el WHERE puede resultar difícil ubicar una condición en específico, aunque bueno, esto último es bastante subjetivo. Finalmente, utilizando JOINS es poco probable que ocurran Productos cartecianos entres tus tablas, es decir que olvides colocar una condición de unión en el WHERE, ya que es fácil identificar sobre que JOIN no se ha definido la cláusula ON respectiva (Observaste que en la primer consulta la Tabla5 no se une con ninguna otra???).

Independientemente de si te inclinas por el WHERE o el JOIN, es importante que tengas una buena administración de indices en tus tablas y de ser posible siempre utilice EXPLAIN para tratar de optimizar tu consulta.

Saludos
Leo.

Etiquetas: clave, doble, multitabla, 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 11:59.