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

[SOLUCIONADO] Consulta no funciona correctamente

Estas en el tema de Consulta no funciona correctamente en el foro de Mysql en Foros del Web. Tengo una consulta que va filtrando los codigos de otras tablas para devolver los resultados filtados. Os explico que contiene cada tabla. -TEMP: Contiene los ...
  #1 (permalink)  
Antiguo 25/04/2014, 02:33
Avatar de temerariomalaga  
Fecha de Ingreso: marzo-2013
Ubicación: Londres
Mensajes: 156
Antigüedad: 11 años, 1 mes
Puntos: 9
Consulta no funciona correctamente

Tengo una consulta que va filtrando los codigos de otras tablas para devolver los resultados filtados.
Os explico que contiene cada tabla.
-TEMP: Contiene los códigos de la tabla Equipo_arbitral que estan disponibles el dia de un partido.
-TEMP3: Contiene los códigos de los árbitros que cumplen una diferencia entre horas (si por ejemplo tienen un partido ya asignado a las 17:00 no se le podrá asignar un partido en el rango desde las 15:15 hasta las 18:45)
-TEMP4: Contiene los códigos de los árbitros que no cumplen la diferencia de horas (Por algún motivo en el if en el que compruebo el rango horario en esta tabla también me inserta los que si cumplen el rango por lo que tengo que filtrarlo posteriormente, cosa que hago en estas consultas)
-TEMP5: Contiene los árbitros que tienen algún partido el mismo dia del partido que se va a asignar
-TEMP6: Contiene los códigos de los árbitros que tienen un partido el mismo dia del partido a asignar y cumplen los rangos horarios.
-TEMP7: Contiene los códigos de los árbitros que tienen un partido el mismo dia del partido y no cumplen los rangos horarios.

Ahora aquí esta la consulta:
Código MySQL:
Ver original
  1. SELECT COUNT(*) INTO @regs FROM EQUIPO_ARBITRAL WHERE Codigo_arbitro IN (SELECT * FROM TEMP) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP4  WHERE codigo NOT IN(SELECT codigo FROM TEMP3)) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP5 WHERE codigo NOT IN(SELECT codigo FROM TEMP7)) AND Cod_localidad=
  2.                 (SELECT Codigo_localidad FROM PABELLON WHERE Codigo_pabellon=pabellon) ORDER BY Apellidos;
  3.     IF(SELECT @regs)>=3 THEN
  4.         SELECT Codigo_arbitro AS 'Cod_arbi', Licencia AS 'Licenc', Nombre AS 'Nom', Apellidos AS 'Ape' FROM EQUIPO_ARBITRAL WHERE Codigo_arbitro IN (SELECT * FROM TEMP) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP4  WHERE codigo NOT IN(SELECT codigo FROM TEMP3)) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP5 WHERE codigo NOT IN(SELECT codigo FROM TEMP7)) AND Cod_localidad=
  5.                     (SELECT Codigo_localidad FROM PABELLON WHERE Codigo_pabellon=pabellon) ORDER BY Apellidos;
  6.     ELSE
  7.         SELECT COUNT(*) INTO @regs2 FROM EQUIPO_ARBITRAL WHERE Codigo_arbitro IN (SELECT * FROM TEMP) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP4  WHERE codigo NOT IN(SELECT codigo FROM TEMP3)) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP5 WHERE codigo NOT IN(SELECT codigo FROM TEMP7)) AND Cod_localidad IN
  8.             (SELECT Codigo_localidad FROM LOCALIDAD WHERE Codigo_sede=(SELECT SEDE.Codigo_sede FROM PABELLON INNER JOIN LOCALIDAD ON PABELLON.Codigo_localidad=LOCALIDAD.Codigo_localidad
  9.             INNER JOIN SEDE ON LOCALIDAD.Codigo_sede=SEDE.Codigo_sede
  10.             WHERE Codigo_pabellon=pabellon)) ORDER BY Apellidos;
  11.         IF(SELECT @regs2)>=3 THEN
  12.             SELECT Codigo_arbitro AS 'Cod_arbi', Licencia AS 'Licenc', Nombre AS 'Nom', Apellidos AS 'Ape' FROM EQUIPO_ARBITRAL WHERE Codigo_arbitro IN (SELECT * FROM TEMP) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP4  WHERE codigo NOT IN(SELECT codigo FROM TEMP3)) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP5 WHERE codigo NOT IN(SELECT codigo FROM TEMP7)) AND Cod_localidad IN
  13.                 (SELECT Codigo_localidad FROM LOCALIDAD WHERE Codigo_sede=(SELECT SEDE.Codigo_sede FROM PABELLON INNER JOIN LOCALIDAD ON PABELLON.Codigo_localidad=LOCALIDAD.Codigo_localidad
  14.                 INNER JOIN SEDE ON LOCALIDAD.Codigo_sede=SEDE.Codigo_sede
  15.                 WHERE Codigo_pabellon=pabellon)) ORDER BY Apellidos;
  16.         ELSE
  17.             SELECT Codigo_arbitro AS 'Cod_arbi', Licencia AS 'Licenc', Nombre AS 'Nom', Apellidos AS 'Ape' FROM EQUIPO_ARBITRAL WHERE Codigo_arbitro IN (SELECT * FROM TEMP) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP4  WHERE codigo NOT IN(SELECT codigo FROM TEMP3)) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP5 WHERE codigo NOT IN(SELECT codigo FROM TEMP7));
  18.         END IF;
  19.     END IF;
No se el por qué pero si intento asignar un partido a las 18:00 de un viernes me aparecen los que ya tienen un partido asignado por ejemplo a las 17:00.
__________________
Málaga Club de Fútbol: Memoria, Compromiso, Fe
  #2 (permalink)  
Antiguo 25/04/2014, 04:22
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Consulta no funciona correctamente

Ufff, eso es un script con varias consultas, divide y vencerás:

1.- Has mirado si cada una por separado da lo que esperas?
2.- Sabes que IN () es una de las clausulas más ineficientes, se puede substitur por LEFT JOIN ... ON y filtrar por NULL o NOT NULL sobre el campo de relación.
3.- Las tablas TEMP realmente contienen lo que dices que contienen. La selección de "un partido a las 18:00" se hace en el momento de crear las tablas TEMP, luego el error podría veir de ahí...
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.
  #3 (permalink)  
Antiguo 25/04/2014, 04:37
Avatar de temerariomalaga  
Fecha de Ingreso: marzo-2013
Ubicación: Londres
Mensajes: 156
Antigüedad: 11 años, 1 mes
Puntos: 9
Respuesta: Consulta no funciona correctamente

Cita:
Iniciado por quimfv Ver Mensaje
Ufff, eso es un script con varias consultas, divide y vencerás:

1.- Has mirado si cada una por separado da lo que esperas?
2.- Sabes que IN () es una de las clausulas más ineficientes, se puede substitur por LEFT JOIN ... ON y filtrar por NULL o NOT NULL sobre el campo de relación.
3.- Las tablas TEMP realmente contienen lo que dices que contienen. La selección de "un partido a las 18:00" se hace en el momento de crear las tablas TEMP, luego el error podría veir de ahí...
He modificado un poco el código porque encontré un error con la tabla TEMP5. Seguiré modificando y si sigo con el mismo problema o cambia ya ya lo posteo.
__________________
Málaga Club de Fútbol: Memoria, Compromiso, Fe
  #4 (permalink)  
Antiguo 25/04/2014, 04:53
Avatar de temerariomalaga  
Fecha de Ingreso: marzo-2013
Ubicación: Londres
Mensajes: 156
Antigüedad: 11 años, 1 mes
Puntos: 9
Respuesta: Consulta no funciona correctamente

Bueno voy a explicar un poco más. En la tabla TEMP7 se repiten tambien los de la tabla TEMP6. Ahora no aparece ningún árbitro.
Voy a reducir el código para centrarnos solo en la consulta principal ya que solucionando esa el resto se solucionarán de las misma forma:
Código MySQL:
Ver original
  1. SELECT Codigo_arbitro AS 'Cod_arbi', Licencia AS 'Licenc', Nombre AS 'Nom', Apellidos AS 'Ape' FROM EQUIPO_ARBITRAL WHERE Codigo_arbitro IN (SELECT * FROM TEMP) AND Codigo_arbitro NOT IN
  2.       (SELECT codigo FROM TEMP4  WHERE codigo NOT IN
  3.             (SELECT codigo FROM TEMP3 WHERE codigo NOT IN
  4.                   (SELECT codigo FROM TEMP5 WHERE codigo NOT IN(SELECT codigo FROM TEMP7 WHERE codigo NOT IN(SELECT codigo FROM TEMP6))))) AND Cod_localidad=
  5.                     (SELECT Codigo_localidad FROM PABELLON WHERE Codigo_pabellon=pabellon) ORDER BY Apellidos;
Si cambia algo ya edito el post.
__________________
Málaga Club de Fútbol: Memoria, Compromiso, Fe

Última edición por temerariomalaga; 25/04/2014 a las 05:15 Razón: nuevos problemas
  #5 (permalink)  
Antiguo 25/04/2014, 05:19
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Consulta no funciona correctamente

Código MySQL:
Ver original
  1. SELECT Codigo_arbitro AS 'Cod_arbi',
  2.        Licencia AS 'Licenc',
  3.        Nombre AS 'Nom',
  4.        Apellidos AS 'Ape'
  5.     FROM EQUIPO_ARBITRAL
  6.     WHERE Codigo_arbitro IN (SELECT * FROM TEMP)
  7.       AND Codigo_arbitro
  8.                   NOT IN (SELECT codigo
  9.                                     FROM TEMP4  
  10.                                     WHERE codigo
  11.                    NOT IN (SELECT codigo
  12.                                  FROM TEMP3
  13.                                  WHERE codigo
  14.                    NOT IN (SELECT codigo
  15.                                  FROM TEMP5
  16.                                  WHERE codigo
  17.                    NOT IN (SELECT codigo
  18.                                  FROM TEMP7
  19.                                  WHERE codigo
  20.                    NOT IN(SELECT codigo
  21.                                  FROM TEMP6)))))
  22.         AND Cod_localidad=(SELECT Codigo_localidad FROM PABELLON WHERE Codigo_pabellon=pabellon)
  23.         ORDER BY Apellidos;

Esa query parece sintacticamente correcta.... el problema es que cada tabla TEMP es en si misma una subquery y no vemos como esta formulada.

Insisto en el tema de eliminar los IN ()
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.

Última edición por quimfv; 25/04/2014 a las 05:26
  #6 (permalink)  
Antiguo 25/04/2014, 05:28
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Consulta no funciona correctamente

Código MySQL:
Ver original
  1. SELECT Codigo_arbitro AS 'Cod_arbi',
  2.        Licencia AS 'Licenc',
  3.        Nombre AS 'Nom',
  4.        Apellidos AS 'Ape'
  5.     FROM EQUIPO_ARBITRAL INNER JOIN
  6.             (SELECT Codigo_localidad FROM PABELLON WHERE Codigo_pabellon=pabellon) Sbc
  7.                   ON EQUIPO_ARBITRAL.Cod_localidad=Sbc.Cod_localidad
  8.     WHERE Codigo_arbitro IN (SELECT * FROM TEMP)
  9.       AND Codigo_arbitro
  10.                   NOT IN (SELECT codigo
  11.                                     FROM TEMP4  
  12.                                     WHERE codigo
  13.                    NOT IN (SELECT codigo
  14.                                  FROM TEMP3
  15.                                  WHERE codigo
  16.                    NOT IN (SELECT codigo
  17.                                  FROM TEMP5
  18.                                  WHERE codigo
  19.                    NOT IN (SELECT codigo
  20.                                  FROM TEMP7
  21.                                  WHERE codigo
  22.                    NOT IN(SELECT codigo
  23.                                  FROM TEMP6)))))
  24.         ORDER BY Apellidos;

Claro que la seleccion de ciudad se podria hacer al obtener TEMP y no seria necesario ponerla aqui....

Código MySQL:
Ver original
  1. SELECT Codigo_arbitro AS 'Cod_arbi',
  2.        Licencia AS 'Licenc',
  3.        Nombre AS 'Nom',
  4.        Apellidos AS 'Ape'
  5.     FROM EQUIPO_ARBITRAL
  6.     WHERE Codigo_arbitro IN (SELECT * FROM TEMP)
  7.       AND Codigo_arbitro
  8.                   NOT IN (SELECT codigo
  9.                                     FROM TEMP4  
  10.                                     WHERE codigo
  11.                    NOT IN (SELECT codigo
  12.                                  FROM TEMP3
  13.                                  WHERE codigo
  14.                    NOT IN (SELECT codigo
  15.                                  FROM TEMP5
  16.                                  WHERE codigo
  17.                    NOT IN (SELECT codigo
  18.                                  FROM TEMP7
  19.                                  WHERE codigo
  20.                    NOT IN(SELECT codigo
  21.                                  FROM TEMP6)))))
  22.         ORDER BY Apellidos;

Si TEMP solo continene EQUIPO_ARBITRALes de la ciudad....


Código MySQL:
Ver original
  1. SELECT Codigo_arbitro AS 'Cod_arbi',
  2.        Licencia AS 'Licenc',
  3.        Nombre AS 'Nom',
  4.        Apellidos AS 'Ape'
  5.     FROM EQUIPO_ARBITRAL
  6.           INNER JOIN (SELECT codigo  
  7.                               FROM TEMP
  8.                               WHERE Codigo
  9.                                    NOT IN (SELECT codigo
  10.                                                 FROM TEMP4  
  11.                                                 WHERE codigo
  12.                                                    NOT IN (SELECT codigo
  13.                                                                 FROM TEMP3
  14.                                                                 WHERE codigo
  15.                                                                   NOT IN (SELECT codigo
  16.                                                                                 FROM TEMP5
  17.                                                                                 WHERE codigo
  18.                                                                                 NOT IN (SELECT codigo
  19.                                                                                               FROM TEMP7
  20.                                                                                               WHERE codigo
  21.                                                                                               NOT IN (SELECT codigo
  22.                                                                                                             FROM TEMP6)))))) SbcTemp
  23.                            ON EQUIPO_ARBITRAL.Codigo_arbitro=SbcTemp.codigo
  24.         ORDER BY Apellidos;

Ya hemos eliminado un IN ().... substituyendolo por un mas eficiente INNER JOIN .... ON

Ya te lo dije en otro post esa tabla es de ARBITROS NO de equipos arbítrales....

En TEMP ya podiamos haber recuperado
Licencia, Nombre, Apellidos, y ciudad y nos ahorrariamos un nivel de subconsultas.....

Código MySQL:
Ver original
  1. SELECT TEMP.Codigo_arbitro AS 'Cod_arbi',
  2.              TEMP.Licencia AS 'Licenc',
  3.              TEMP.Nombre AS 'Nom',
  4.              TEMP.Apellidos AS 'Ape'
  5.              FROM TEMP
  6.              WHERE TEMP.Codigo_arbitro
  7.                    NOT IN (SELECT codigo
  8.                                 FROM TEMP4  
  9.                                 WHERE codigo
  10.                                 NOT IN (SELECT codigo
  11.                                              FROM TEMP3
  12.                                              WHERE codigo
  13.                                              NOT IN (SELECT codigo
  14.                                                           FROM TEMP5
  15.                                                           WHERE codigo
  16.                                                           NOT IN (SELECT codigo
  17.                                                                        FROM TEMP7
  18.                                                                        WHERE codigo
  19.                                                                         NOT IN (SELECT codigo
  20.                                                                                       FROM TEMP6)))))
  21.              ORDER BY TEMP.Apellidos;

Simplificando....

NOT IN () se substituye por

...
tabla1 t1 LEFT JOIN tabla2 t2 ON t1.campo=t2.campo
WHERE t2.campo IS NULL
...
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.

Última edición por quimfv; 25/04/2014 a las 05:53
  #7 (permalink)  
Antiguo 25/04/2014, 11:13
Avatar de temerariomalaga  
Fecha de Ingreso: marzo-2013
Ubicación: Londres
Mensajes: 156
Antigüedad: 11 años, 1 mes
Puntos: 9
Respuesta: Consulta no funciona correctamente

He cojido papel y lápiz y he reestructurado todo y lo he simplificado mycho, funcionando ahora todo a la perfección. Ahora tendria TEMP que son todos los arbitros disponibles, TEMP3 que son los que tienen partido un dia distinto, TEMP4 los que tienen el mismo dia y a raiz de TEMP4 saco TEMP5 que son los que cumplen la diferencia horaria y TEMP6 que son los que no. Teniendo esto ahora todo es mucho más sencillo porque solo tengo que obtener los arbitros disponibles (TEMP) y excluir a los que no cumplen la diferencia horaria (TEMP6).
Todo esto dejo aquí el código para que veas que nos hemos comido demasiado la cabeza los dos. De todas formas muchas gracias por tu ayuda @quimfv
Código MySQL:
Ver original
  1. SELECT COUNT(*) INTO @regs FROM EQUIPO_ARBITRAL WHERE Codigo_arbitro IN (SELECT * FROM TEMP) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP6) AND Cod_localidad=
  2.                 (SELECT Codigo_localidad FROM PABELLON WHERE Codigo_pabellon=pabellon) ORDER BY Apellidos;
  3.     IF(SELECT @regs)>=3 THEN
  4.         SELECT Codigo_arbitro AS 'Cod_arbi', Licencia AS 'Licenc', Nombre AS 'Nom', Apellidos AS 'Ape' FROM EQUIPO_ARBITRAL WHERE Codigo_arbitro IN
  5.             (SELECT * FROM TEMP) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP6) AND Cod_localidad=
  6.                     (SELECT Codigo_localidad FROM PABELLON WHERE Codigo_pabellon=pabellon) ORDER BY Apellidos;
  7.     ELSE
  8.         SELECT COUNT(*) INTO @regs2 FROM EQUIPO_ARBITRAL WHERE Codigo_arbitro IN (SELECT * FROM TEMP) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP6) AND Cod_localidad IN
  9.             (SELECT Codigo_localidad FROM LOCALIDAD WHERE Codigo_sede=(SELECT SEDE.Codigo_sede FROM PABELLON INNER JOIN LOCALIDAD ON PABELLON.Codigo_localidad=LOCALIDAD.Codigo_localidad
  10.                 INNER JOIN SEDE ON LOCALIDAD.Codigo_sede=SEDE.Codigo_sede
  11.                     WHERE Codigo_pabellon=pabellon)) ORDER BY Apellidos;
  12.         IF(SELECT @regs2)>=3 THEN
  13.             SELECT Codigo_arbitro AS 'Cod_arbi', Licencia AS 'Licenc', Nombre AS 'Nom', Apellidos AS 'Ape' FROM EQUIPO_ARBITRAL WHERE Codigo_arbitro IN
  14.                 (SELECT * FROM TEMP) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP6) AND Cod_localidad IN
  15.                     (SELECT Codigo_localidad FROM LOCALIDAD WHERE Codigo_sede=(SELECT SEDE.Codigo_sede FROM PABELLON INNER JOIN LOCALIDAD ON PABELLON.Codigo_localidad=LOCALIDAD.Codigo_localidad
  16.                         INNER JOIN SEDE ON LOCALIDAD.Codigo_sede=SEDE.Codigo_sede
  17.                             WHERE Codigo_pabellon=pabellon)) ORDER BY Apellidos;
  18.         ELSE
  19.             SELECT Codigo_arbitro AS 'Cod_arbi', Licencia AS 'Licenc', Nombre AS 'Nom', Apellidos AS 'Ape' FROM EQUIPO_ARBITRAL WHERE Codigo_arbitro IN (SELECT * FROM TEMP) AND Codigo_arbitro NOT IN(SELECT codigo FROM TEMP6);
  20.         END IF;
  21.     END IF;
__________________
Málaga Club de Fútbol: Memoria, Compromiso, Fe

Etiquetas: correctamente, join, select, 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 13:09.