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

Problema con consulta

Estas en el tema de Problema con consulta en el foro de Mysql en Foros del Web. Hola chicos alguien podría ayudarme con esto, veran estoy haciendo una consulta a 4 tablas y todo bien bueno a medias para hacer la consulta ...
  #1 (permalink)  
Antiguo 09/12/2011, 23:01
Avatar de arsenal  
Fecha de Ingreso: agosto-2008
Mensajes: 65
Antigüedad: 15 años, 7 meses
Puntos: 2
Problema con consulta

Hola chicos alguien podría ayudarme con esto,

veran estoy haciendo una consulta a 4 tablas y todo bien bueno a medias para hacer la consulta uso RIGHT JOIN y todo bien el problema es a la hora de traer resultados, o sea

tengo una tabla llamada personas y una telefonos bien para jalar los datos uso RIGHT JOIN y todo lindo me muestra resultados y todo bien todos las personas registradas en la tabla personas tienen un solo telefono en la tabla telefono, el problema es cuando una de esas personas tiene mas de uno, por ejemplo 2 ó 3 teléfonos en la tabla telefono, o sea

personas
id_persona
nombre

telefonos
id_tel
id_persona
numero


si tengo 3 registros con el mismo id_persona , o sea una persona tiene 3 numeros solo me regresa el último ingresado


mi pregunta es como puedo lograr para que se me impriman los 3 numeros de esa persona en la misma consulta

y es que lo he logra peo muy salvaje un while sobre cada persona y eso no se no me gusta

Saludos
  #2 (permalink)  
Antiguo 10/12/2011, 06:18
Avatar de 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, 4 meses
Puntos: 2658
Respuesta: Problema con consulta

Postea la consulta usada.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 10/12/2011, 08:29
Avatar de arsenal  
Fecha de Ingreso: agosto-2008
Mensajes: 65
Antigüedad: 15 años, 7 meses
Puntos: 2
Respuesta: Problema con consulta

Hola buen día, claro
Código MySQL:
Ver original
  1. SELECT p.titulo titulo, f.idioma idioma, f.sala sala, h.hora hora
  2.         FROM cartelera c
  3.         RIGHT JOIN peliculas p ON c.pelicula = p.id
  4.         RIGHT JOIN funciones f ON c.tipo_funcion = f.id
  5.         RIGHT JOIN horarios h ON f.id = h.funcion
  6.         WHERE c.cine = $cine
  7.         GROUP BY c.pelicula

Esa es mi consulta lo que quiero lograr es

que me imprima de una sola consulta lo siguente,

Nombre de la pelicula
funcion: doblada sala 1 14:00 17:00 19:00
funcion subtitulada sala 2 13:00 15:00 17:00
funcion espanol sala 3 14:30 17:30 19:30


como pueden ver la tabla funciones tiene mas de un registro en la que se dice la sala y el idioma en el que esta

la tabla horario tambien tiene varios registros por funcion en este casa 3 registros por funcion ya que el campo es tipo time no varchar.


Saludos espero sea posible sacar estos resultados de una sola consulta y es como dije antes lo puedo hacer con muchos whiles pero creo q no es la forma correcta

Saludos
  #4 (permalink)  
Antiguo 10/12/2011, 09:41
Avatar de 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, 4 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)
  #5 (permalink)  
Antiguo 10/12/2011, 10:33
Avatar de arsenal  
Fecha de Ingreso: agosto-2008
Mensajes: 65
Antigüedad: 15 años, 7 meses
Puntos: 2
Respuesta: Problema con consulta

Hola gnzsoloyo muchas gracias por ayudarme muchas cosas que no sabia y que hacia mal hice bien en consultar este problema para hacer bien las cosas.

El codigo va bien pero sigo teniendo el problema me imprime solo el primer registro.



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.id = f.cartelera
  8.     INNER JOIN horarios h ON f.id = h.funcion
  9. WHERE c.cine = $cine
  10. GROUP BY c.pelicula

Un cine publica una peli y esta puede estar en varias salas en idiomas diferentes y horarios diferentes, entonces ese es el problema

la tabla cartelera no sirva mas para hacer link con cine y la peli
la tabla funciones es donde esta el tipo funcion (idioma,sala,etc,)
la tabla horario pues la hora que puede tener cada funcion (campo hora time)

aca el problema que si en funciones tengo 2 veces la misma cartelera (enlace cine y peli) pero con diferente idioma y horarios solo me muestra el primer registro que hice por que?

lo de los horarios es de lujo me los concatena bien

una pregunta extra vera que en la consulta en el where ay una variable $cine esa variable trae los id de los cines en total son 5 hay forma de declararlos para no hacer esa consula yo recuerdo que vi un funcion en el where algo asi FUNCIONQUEDESCONOSCO(3,6,8) y solo mostraria los resultados de esos id o no es para eso?


muchas gracias por su tiempo
  #6 (permalink)  
Antiguo 10/12/2011, 10:36
Avatar de 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, 4 meses
Puntos: 2658
Respuesta: Problema con consulta

El problema es que estás agrupando sólo por película, y tienes que hacerlo por cada discriminante (idioma, sala, etc) que hayas de usar.
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.id = f.cartelera
  8.     INNER JOIN horarios h ON f.id = h.funcion
  9. WHERE c.cine = $cine
  10. GROUP BY titulo, idioma, sala;

En cuando a la función que mencionas, puede usarse una u otra según cómo venga el dato en esa variable.
Si son IDs separados por comas, lo más simple sería:
Código MySQL:
Ver original
  1.     c.cine,
  2.     p.titulo,
  3.     f.idioma,
  4.     f.sala,
  5.     GROUP_CONCAT(DISTINCT h.hora) horarios
  6.     cartelera c
  7.     INNER JOIN peliculas p ON c.pelicula = p.id
  8.     INNER JOIN funciones f ON c.id = f.cartelera
  9.     INNER JOIN horarios h ON f.id = h.funcion
  10. WHERE c.cine IN($cine)
  11. GROUP BY cine, titulo, idioma, sala;

¿Puedes postear el contenido de una de esas variables?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 10/12/2011, 11:01
Avatar de arsenal  
Fecha de Ingreso: agosto-2008
Mensajes: 65
Antigüedad: 15 años, 7 meses
Puntos: 2
Respuesta: Problema con consulta

$cine son los ids de los negocios que esten en la categoria cines, entonces preguntaba por esa funcion pues antes que nada haga una consulta para jalar todos los id de negocios, son enteros y como son poquitos pues se me hace una burrada :P hacer eso y queria saber si puedo hacer eso IN(4,7,9,10,15) esos son los id de los negocios que son cines.

[/HIGHLIGHT]

saludos

Última edición por arsenal; 10/12/2011 a las 11:12
  #8 (permalink)  
Antiguo 10/12/2011, 13:09
Avatar de 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, 4 meses
Puntos: 2658
Respuesta: Problema con consulta

Ya te pasé un ejemplo.
¿Lo probase?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #9 (permalink)  
Antiguo 11/12/2011, 00:03
Avatar de arsenal  
Fecha de Ingreso: agosto-2008
Mensajes: 65
Antigüedad: 15 años, 7 meses
Puntos: 2
Respuesta: Problema con consulta

Hola gnzsoloyo si lo probe y nada use WHERE c.cine IN(4,7,9,10,15) y nada

Lo que no quiero es hacer una consulta para sacar los cines son pocos y conosco sus ids ay alguna forma o afuerzas tiene que ser asi

Saludos
  #10 (permalink)  
Antiguo 11/12/2011, 06:28
Avatar de 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, 4 meses
Puntos: 2658
Respuesta: Problema con consulta

Cita:
Hola gnzsoloyo si lo probe y nada
Yo, al menos, no termino de entender a qué te refieres con nada.
¿Puedes explicar un poco más claramente qué te devuelve, si te devuelve, cuál de las sentencias de ejemplo probaste, en qué forma la probaste y por qué dices que no es lo esperado?
Tal y como me respondes, no puede ni siquiera inferirlo.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #11 (permalink)  
Antiguo 11/12/2011, 08:20
Avatar de 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, 4 meses
Puntos: 2658
Respuesta: Problema con consulta

Bien, voy a mostrarte por qué te decía que esos dos ejemplos deberían dar el resultado que tu esperas.

Cree y cargue con datos cuatro tablas basadas en la descripción del primer post. Las tablas son:
Código MySQL:
Ver original
  1. DROP TABLE IF EXISTS `funciones`;
  2. CREATE TABLE  `funciones` (
  3.   `idioma` varchar(45) NOT NULL,
  4.   `sala` varchar(45) NOT NULL,
  5.   PRIMARY KEY  USING BTREE (`id`)
  6.  
  7. DROP TABLE IF EXISTS `pelicula`;
  8. CREATE TABLE  `pelicula` (
  9.   `titulo` varchar(45) NOT NULL,
  10.   PRIMARY KEY  USING BTREE (`id`)
  11.  
  12. DROP TABLE IF EXISTS `horarios`;
  13. CREATE TABLE  `horarios` (
  14.   `hora` time NOT NULL,
  15.   `funcion` int(10) unsigned NOT NULL,
  16.   PRIMARY KEY  USING BTREE (`id`),
  17.   KEY `FK_horarios_1` (`funcion`),
  18.   CONSTRAINT `FK_horarios_1` FOREIGN KEY (`funcion`) REFERENCES `funciones` (`id`)
  19.  
  20. DROP TABLE IF EXISTS `cartelera`;
  21. CREATE TABLE  `cartelera` (
  22.   `pelicula` int(10) unsigned NOT NULL,
  23.   `cine` int(10) unsigned NOT NULL,
  24.   `tipo_funcion` int(10) unsigned NOT NULL,
  25.   PRIMARY KEY  USING BTREE (`pelicula`,`tipo_funcion`,`cine`),
  26.   KEY `FK_cartelera_1` (`tipo_funcion`),
  27.   CONSTRAINT `FK_cartelera_1` FOREIGN KEY (`tipo_funcion`) REFERENCES `funciones` (`id`)

Sobre esta base, hice las dos consultas con sus resultados:
Código MySQL:
Ver original
  1. mysql> SELECT
  2.     ->     p.titulo,
  3.     ->     f.idioma,
  4.     ->     CONCAT('Sala ', f.sala) sala,
  5.     ->     CAST(GROUP_CONCAT(DISTINCT DATE_FORMAT(h.hora, '%k:%i') SEPARATOR ' - ') AS CHAR(200)) horarios
  6.     -> FROM
  7.     ->     cartelera c
  8.     ->     LEFT JOIN pelicula p ON c.pelicula = p.id
  9.     ->     LEFT JOIN funciones f ON c.tipo_funcion = f.id
  10.     ->     LEFT JOIN horarios h ON f.id = h.funcion
  11.     -> GROUP BY pelicula, idioma, sala;
  12. +--------------------+-------------+--------+---------------+
  13. | titulo             | idioma      | sala   | horarios      |
  14. +--------------------+-------------+--------+---------------+
  15. | Cars 2             | doblada     | Sala 1 | 14:30 - 19:30 |
  16. | Cars 2             | espa±ol     | Sala 3 | 16:30 - 19:00 |
  17. | Cars 2             | subtitulada | Sala 1 | 18:00 - 22:00 |
  18. | Cars 2             | subtitulada | Sala 2 | 16:00 - 19:00 |
  19. | Coraline           | doblada     | Sala 3 | 18:00         |
  20. | Coraline           | subtitulada | Sala 1 | 18:00 - 22:00 |
  21. | A±o Nuevo          | doblada     | Sala 1 | 14:30 - 19:30 |
  22. | A±o Nuevo          | subtitulada | Sala 2 | 19:00 - 16:00 |
  23. | Rapido y Furioso 5 | doblada     | Sala 3 | 18:00         |
  24. | Rapido y Furioso 5 | espa±ol     | Sala 3 | 19:00 - 16:30 |
  25. +--------------------+-------------+--------+---------------+
  26. 10 rows in set, 1 warning (0.00 sec)
  27.  
  28. mysql> SELECT
  29.     ->     p.titulo,
  30.     ->     f.idioma,
  31.     ->     CONCAT('Sala ', f.sala) sala,
  32.     ->     CAST(GROUP_CONCAT(DISTINCT DATE_FORMAT(h.hora, '%k:%i') SEPARATOR ' - ') AS CHAR(200)) horarios
  33.     -> FROM
  34.     ->     cartelera c
  35.     ->     INNER JOIN pelicula p ON c.pelicula = p.id
  36.     ->     LEFT JOIN funciones f ON c.tipo_funcion = f.id
  37.     ->     LEFT JOIN horarios h ON f.id = h.funcion
  38.     -> GROUP BY pelicula, idioma, f.sala;
  39. +--------------------+-------------+--------+---------------+
  40. | titulo             | idioma      | sala   | horarios      |
  41. +--------------------+-------------+--------+---------------+
  42. | Cars 2             | doblada     | Sala 1 | 14:30 - 19:30 |
  43. | Cars 2             | espa±ol     | Sala 3 | 19:00 - 16:30 |
  44. | Cars 2             | subtitulada | Sala 1 | 18:00 - 22:00 |
  45. | Cars 2             | subtitulada | Sala 2 | 16:00 - 19:00 |
  46. | Coraline           | doblada     | Sala 3 | 18:00         |
  47. | Coraline           | subtitulada | Sala 1 | 18:00 - 22:00 |
  48. | A±o Nuevo          | doblada     | Sala 1 | 14:30 - 19:30 |
  49. | A±o Nuevo          | subtitulada | Sala 2 | 16:00 - 19:00 |
  50. | Rapido y Furioso 5 | doblada     | Sala 3 | 18:00         |
  51. | Rapido y Furioso 5 | espa±ol     | Sala 3 | 19:00 - 16:30 |
  52. +--------------------+-------------+--------+---------------+
  53. 10 rows in set (0.00 sec)
Como podrás ver, las consultas efectivamente devuelven resultados como lo indicas. La diferencia esencia es que incluí algunas funciones de salida para evitar problemas con la representación de las columnas, porque GROUP_CONCAT() puede devolver un string o un BLOB dependiendo del conector usado y de la versión de MySQL.

Ahora bien: ¿Cuál es entonces el problema que se te presenta?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #12 (permalink)  
Antiguo 11/12/2011, 11:23
Avatar de arsenal  
Fecha de Ingreso: agosto-2008
Mensajes: 65
Antigüedad: 15 años, 7 meses
Puntos: 2
Respuesta: Problema con consulta

Hola gnzsoloyo buen día,

Si, me toco volver a hacer la bd algun problema tenia la otra ahora me van perfecto. Lo que te comentaba y lo siento por no explicarme el tema me tiene estesado.

Vera tengo una seccion donde se mostrara la carteleras y en esa seccion hago dos consultas la primera es para traer los negocios que esten marcados como cine en total son 5 y dentro del while de esa primera consulta hago la segunda que seria esta que me hizo, la pregunta es puedo evitar hacer la primer consulta si conosco los IDs de los negocios que son cines aunque le pienso un poco mas y creo que no es posible pues la primera me arroja los cines y dentro de cada fila de cine sus peliculas, por eso preguntaba de la funcion IN pero no creo que funcione asi y si funcionara me imagino que me arrojaria todas las carteleras de todos los cines sin clasificar sin decir de que cine es. no



En la primera consulta le tira un warning eso que indica 10 rows IN SET, 1 warning (0.00 sec)

Como hace los test asi esta muy bueno

ahora que veo los resultados es posible que los titulos repetidos no se impriman todos solo uno hacer una agrupacion? es posible

Saludos

Etiquetas: join, registros, 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 09:22.