Ver Mensaje Individual
  #4 (permalink)  
Antiguo 10/12/2011, 09:41
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: Problema con consulta

Hay algún que otro detalle:
- ¿Por qué usas RIGHT JOIN? No me parece la elección correcta en tu contexto. RIGHT JOIN devuelve todo lo que está en la segunda tabla, haya o no coincidencias con la primera. En ese sentido, la presencia de la tabla "cartelera" sirve sólo para restringir la búsqueda del WHERE, pero no da resultados correctos en la tabla, entre otras cosas porque te devolverá la lista completa de horarios, sin importar a qué pertenezcan, combinada con la de funciones, sin distinción de pertenencia, etc. Esto es así porque el JOIN se produce en este caso de derecha a izquierda.
- Además, si el objetivo de esa primera tabla es obtener el nombre del cine y el tipo de función, y estos datos está siempre, entonces no correspondería usar ni RIGHT ni LEFT, sino INNER, ya que toda película debe pasarse forzosamente en un cine, toda película debe tener un idioma, debe tener un tipo de función y un horario. No son opcionales, cuya búsqueda es el objetivo de LEFT y RIGHT.
- Respecto a la última columna, si lo que quieres es agrupar todos los horarios en un sólo campo, lo que tienes que hacer es leer el manual de referencia y buscar las funciones que se usan con GROUP BY. Allí encontrarás GROUP_CONCAT(), que sirve para eso.

Veamos. Si toda película se pasa en un cine, tiene una función, un idioma, una sala y un horario, esto debería funcionar:
Código MySQL:
Ver original
  1.     p.titulo,
  2.     f.idioma,
  3.     f.sala,
  4.     GROUP_CONCAT(DISTINCT h.hora) horarios
  5.     cartelera c
  6.     INNER JOIN peliculas p ON c.pelicula = p.id
  7.     INNER JOIN funciones f ON c.tipo_funcion = f.id
  8.     INNER  JOIN horarios h ON f.id = h.funcion
  9. WHERE c.cine = $cine
  10. GROUP BY c.pelicula;
De hecho, debería dar el mismo resultado que esto:
Código MySQL:
Ver original
  1.     p.titulo,
  2.     f.idioma,
  3.     f.sala,
  4.     GROUP_CONCAT(DISTINCT h.hora) horarios
  5.     cartelera c
  6.     LEFT JOIN peliculas p ON c.pelicula = p.id
  7.     LEFT JOIN funciones f ON c.tipo_funcion = f.id
  8.     LEFT JOIN horarios h ON f.id = h.funcion
  9. WHERE c.cine = $cine
  10. GROUP BY c.pelicula
Si esta ultima devuelve más registros, es porque alguna de las tablas no tiene el valor que corresponde, es decir, el esquema de relaciones de esa película no está completo.

Tips:
1) No uses "ID" como nombre de un identificador de tabla, es propenso a confusiones porque los usas en todos lados. Agrégale algún prefijo que identifique la tabla (pelicula_id, funcion_id, cine_id); de ese modo te resultará mucho más sencillo recordar a qué "id" te estás refiriendo, y ocasionalmente puede facilitarte la escritura de las consultas.
2) Los alias son una muy buena idea, especialmente cuando se trata de tablas de nombres largos. Pero no necesitas poner el alias si lo que vas a poner es lo mismo que el nombre de la columna. En ese caso no se necesita, porque el nombre de la tabla origen no sale luego en la tabla resultado. Lo único que haces es agregar texto sin funcionalidad, y ensuciar el código.
3) Sí debes ponerle alias a toda columna afectada por funciones, porque en ese caso la tabla resultado tendrá por nombre el mismo texto de la función (por ejemplo "GROUP_CONCAT(DISTINCT h.hora)", cosa que a la hora de programar causa inconvenientes.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)