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

Consultas múltiples a múltiples tablas ¿Cómo lo hago?

Estas en el tema de Consultas múltiples a múltiples tablas ¿Cómo lo hago? en el foro de Mysql en Foros del Web. Hola a tod@s. Esto es un poco complicado, a ver si logro explicarme. Tengo varias tablas (tengo más, esto solo son unos pocos ejemplos), algunas ...
  #1 (permalink)  
Antiguo 24/04/2013, 21:07
 
Fecha de Ingreso: junio-2003
Mensajes: 104
Antigüedad: 20 años, 9 meses
Puntos: 0
Consultas múltiples a múltiples tablas ¿Cómo lo hago?

Hola a tod@s.

Esto es un poco complicado, a ver si logro explicarme.

Tengo varias tablas (tengo más, esto solo son unos pocos ejemplos), algunas relacionadas por un número id, de este estilo:

Código MySQL:
Ver original
  1. tabla peliculas
  2.  
  3. id_pelicula     url_pelicula      titulo_pelicula
  4. 5               el-padrino        El Padrino
  5.  
  6. ----------------------------
  7.  
  8. tabla directores
  9.  
  10. id_director    id_director_pelicula     nombre_director            pais_director
  11. 3              5                        Francis Ford Coppola       Estados Unidos
  12.  
  13. ----------------------------
  14.  
  15. tabla fichas
  16.  
  17. id_ficha      id_ficha_pelicula     sinopsis_ficha       genero_ficha        subgenero_ficha
  18. 1             5                     sinopsis...          2                   4
  19.  
  20. ----------------------------
  21.  
  22. tabla generos
  23.  
  24. id_genero               nombre_genero       url_genero
  25. 2                       Drama               drama
  26. 4                       Mafia               mafia
  27.  
  28. ----------------------------
  29.  
  30. tabla videos
  31.  
  32. id_video    id_video_pelicula         titulo_video               url_video
  33. 1           5                         Trailer de el Padrino      trailer-padrino
  34. 2           5                         Final de El Padrino        final-padrino
  35. 3           5                         Teaser de El Padrino       teaser-padrino

Me gustaría obtener un resultado de este estilo:

Cita:
ID: 5
Película: El Padrino
Director: Francis Ford Coppola (Estados Unidos)
Sinopsis: sinopsis...
Géneros: Drama, Mafia
Vídeos (3)
- Trailer de el Padrino
- Final de El Padrino
- Teaser de El Padrino
Los datos los saco a partir de la URL con $_GET['url_pelicula'], es decir...

¿Cómo podría hacerlo todo en una misma consulta sin tener que hacer multitud de consultas diferentes por página?

Código MySQL:
Ver original
  1. SELECT * FROM peliculas, fichas WHERE fichas.id_ficha_pelicula = peliculas.id_pelicula AND peliculas.url_pelicula = '$url_pelicula' LIMIT 1

De aquí saco $id_pelicula, $genero_pelicula, $subgenero_pelicula, etc... que utilizo en las siguientes consultas

Código MySQL:
Ver original
  1. SELECT nombre_director, pais_director FROM directores WHERE id_director_pelicula = '$id_pelicula' LIMIT 1
  2.  
  3. SELECT nombre_genero, url_genero FROM generos WHERE id_genero = '$genero_ficha' LIMIT 1
  4.  
  5. SELECT nombre_genero, url_genero FROM generos WHERE id_genero = '$subgenero_ficha' LIMIT 1
  6.  
  7. SELECT COUNT(id_video) FROM videos WHERE id_video_pelicula ='$id_pelicula'
  8.  
  9. SELECT titulo_video, url_video FROM videos WHERE id_video_pelicula ='$id_pelicula'

etc... Como veis para mostrar unos pocos datos hago mil consultas, toda una locura

¿Se podría hacer como digo todo en una consulta? ¿Cuál sería la más eficiente?

Gracias de antemano al que se haya leído todo este lío. Espero haberme explicado bien. Quizás el problema es la estructura de la base de datos, que es un caos ilógico XD

Cualquier ayuda es apreciada.

¡Un saludo!

Última edición por PYTUFYN; 24/04/2013 a las 21:58
  #2 (permalink)  
Antiguo 24/04/2013, 23:57
sjj
 
Fecha de Ingreso: octubre-2008
Mensajes: 213
Antigüedad: 15 años, 5 meses
Puntos: 12
Respuesta: Consultas múltiples a múltiples tablas ¿Cómo lo hago?

¿Y por qué no haces todo en una sola consulta con inner join? ¿Cuál sería el problema?
  #3 (permalink)  
Antiguo 25/04/2013, 06:46
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Consultas múltiples a múltiples tablas ¿Cómo lo hago?

Si se puede hacer con una sola consulta usando join como te ha dicho... pero antes tienes un error de diseño en la tabla directores....

La relación pelicula-director es n:m puesto que una pelicula puede tener varios directores y un director puede haber dirigido varias peliculas... Si quieres te concedo que hagas la reduccion de que una pelicula siempre tendrá un solo director... aún suponiendo esto sigues con un error de diseño

Si la relacion es N:M necesitas tres tablas

Peliculas
idPelicula
titulo
...

RelPeliculasDirectores
idPelicula
idDirector

Directores
idDirector
nombre
...

esta estructura permite que una pelicula tenga n directores y que un director haya dirigido m peliculas minimizando el espacio de almacenamiento de datos.

Si la relación es 1:N


Necesitas dos tablas como ya tienes pero con los identificadores de relacion donde toca

Peliculas
idPelicula
titulo
idDirector
...

Directores
idDirector
Nombre
...

esto permite saber el director de cada pelicula, sin tener que duplicar directores en su tabla. Tu tenias el idPelicula en la tabla directores lo que te obligaba a repetyir los datos del director para cada pelicula que haya dirigido.


La misma explicación se podria aplicar a la relacion entre peliculas y generos... pero vamos a suponer que con genero y subgenero tienes bastante.


Código MySQL:
Ver original
  1. SELECT * FROM ((peliculas p INNER JOIN directores d ON p.idDirector=d.idDirector)
  2.                           INNER JOIN
  3.                                   ((fichas f INNER JOIN generos gg ON f.genero_ficha=gg.id_genero)
  4.                                                  INNER JOIN generos sg ON f.subgenero_ficha=sg.id_genero)
  5.                                 ON p.idPelicula=f.id_ficha_pelicula)
  6.                           INNER JOIN videos v ON p.idPelicula=v.id_video_pelicula
  7. WHERE p.url_pelicula = '$url_pelicula';

Aquí la solución para el caso en que solo tengas un director por pelicula....

Esto te dara todos los campos te todas las tablas... no te gustará el resultado por que te va a repetir los datos de una pelicula tantas veces como videos tengas...

Yo te aconsejo que trates el resultado en la programacion externa para mostrar loque quieres... directemente en mysql .... deberías usar group concat sobre los videos ... pero no es estandar y a mi no me gusta.

Usa LEFT JOIN si alguno de los campos no tiene contenido....
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.

Última edición por quimfv; 25/04/2013 a las 06:53
  #4 (permalink)  
Antiguo 25/04/2013, 14:31
 
Fecha de Ingreso: junio-2003
Mensajes: 104
Antigüedad: 20 años, 9 meses
Puntos: 0
Respuesta: Consultas múltiples a múltiples tablas ¿Cómo lo hago?

Hola, gracias quimfv por tu respuesta, ya he conseguido lo que quería.

Por no abrir otro tema distinto y aprovechando esta consulta, ¿Cómo podría hacer una sola consulta de estas dos consultas? Lo he intentado de mil maneras y siempre me da error (no tengo muchos conocimientos de mysql)

Consulta 1

Código MySQL:
Ver original
  1. FROM juegos
  2. LEFT JOIN fichas ON fichas.id_juego_ficha = juegos.id_juego
  3. LEFT JOIN analisis ON analisis.id_juego_analisis = juegos.id_juego
  4. LEFT JOIN videos ON videos.id_juego_video = juegos.id_juego
  5. WHERE url_juego = '$url_ficha'

Consulta 2

Código MySQL:
Ver original
  1.   COUNT(CASE WHEN tipo_truco = '1' THEN id_truco END) AS t1,
  2.   COUNT(CASE WHEN tipo_truco = '2' THEN id_truco END) AS t2,
  3.   COUNT(CASE WHEN tipo_truco = '3' THEN id_truco END) AS t3,
  4.   COUNT(CASE WHEN tipo_truco = '4' THEN id_truco END) AS t4,
  5.   COUNT(id_truco) AS Total
  6. FROM trucos WHERE id_juego_truco = '$id_juego'");

Perdonad si son cosas básicas, pero como digo soy muy novato y si escribo es porque lo he intentado un millón de veces y he leído mil cosas y sigo como al principio.

Un saludo.
  #5 (permalink)  
Antiguo 25/04/2013, 15:56
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Consultas múltiples a múltiples tablas ¿Cómo lo hago?

Mira en el manual el tema GROUP BY
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.
  #6 (permalink)  
Antiguo 25/04/2013, 16:34
 
Fecha de Ingreso: junio-2003
Mensajes: 104
Antigüedad: 20 años, 9 meses
Puntos: 0
Respuesta: Consultas múltiples a múltiples tablas ¿Cómo lo hago?

Hola.

Ya he buscado eso y muchas cosas más, pero todavía no me aclaro muy bien. Y todas las cosas que intento me dan error . Por eso pongo las dos consultas concretas que me gustaría unir en una sola, por si alguien sabría hacerla sin errores.

Gracias igualmente. Seguiré documentándome mientras tanto.
  #7 (permalink)  
Antiguo 29/04/2013, 17:25
 
Fecha de Ingreso: junio-2003
Mensajes: 104
Antigüedad: 20 años, 9 meses
Puntos: 0
Respuesta: Consultas múltiples a múltiples tablas ¿Cómo lo hago?

Finalmente he conseguido unir todo en una consulta y me funciona perfectamente:

Código MySQL:
Ver original
  1. SELECT juegos.*,
  2. COUNT(DISTINCT videos.id_video) AS total_videos,
  3. COUNT(DISTINCT (CASE WHEN tipo_truco = 1 THEN id_truco END)) AS t1,
  4. COUNT(DISTINCT (CASE WHEN tipo_truco = 2 THEN id_truco END)) AS t2,
  5. COUNT(DISTINCT (CASE WHEN tipo_truco = 3 THEN id_truco END)) AS t3,
  6. COUNT(DISTINCT (CASE WHEN tipo_truco = 4 THEN id_truco END)) AS t4,
  7. COUNT(DISTINCT trucos.id_truco) AS total_trucos
  8. FROM juegos
  9. LEFT JOIN fichas ON juegos.id_juego = fichas.id_juego_ficha
  10. LEFT JOIN analisis ON juegos.id_juego = analisis.id_juego_analisis
  11. LEFT JOIN trucos ON juegos.id_juego = trucos.id_juego_truco
  12. LEFT JOIN videos ON juegos.id_juego = videos.id_juego_video
  13. WHERE juegos.url_juego = '$url_ficha'
  14. GROUP BY juegos.id_juego

Pero sigo sin saber cómo poder mostrar todos los vídeos que coincidan juegos.id_juego = videos.id_juego_video en esa misma consulta. No sé si se podrá hacer tal cosa... Si no tendré que hacer otra consulta por separado (previamente habiendo definido $id_juego):

Código MySQL:
Ver original
  1. SELECT * FROM videos WHERE id_juego_video = '$id_juego'

Por otra parte, en la tabla juegos tengo dos campos, visitas_temporales y visitas_totales, que actualizo de siguiente manera cada vez que se entra a la ficha del juego:

Código MySQL:
Ver original
  1. UPDATE juegos SET visitas_totales = visitas_totales +1, visitas_temporales = visitas_temporales +1 WHERE juegos.url_juego = '$url_ficha'

Imagino que esto ya sí que no puedo unirlo a la primera consulta y tengo que hacerla por separado ¿no?

¿Alguna idea para unirlo todo?

Por cierto, y esto ya es lo último que pregunto ¿cuántas consultas distintas en un mismo documento se considerarían "aceptables"? Sé que esto que pregunto es muy relativo y depende de la cantidad de registros y del tipo de consultas, pero bueno, por saber... Porque si en un documento para mostrar todos los datos y hacer todo lo que necesitas requieres por ejemplo de 10 consultas distintas y en ese momento hay 10 personas online, serían 100 consultas simultáneas... Supongo que lo ideal sería 1 consulta por documento ¿no?

Ahora sí que me despido y dejo de divagar... Saludos!

Etiquetas: select, sql, tabla, tablas
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 22:14.