Ver Mensaje Individual
  #8 (permalink)  
Antiguo 31/01/2015, 15:47
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: Crear consultas para base de datos Mysql

Bueno, recién ahora la cosa se pone interesante. SIn códigos es todo muy aburrido.... Lo siente.

Para poder entender como se resuelven las cosas en BBDD y SQL, tienes que razonar de modo algo diferente a lo que haces en programación. Eso tenlo presente porque es una de las primeras reglas que te enseñan en la asignatura, cuando la cursas en la universidad. Y es cierto.
No empieces tratando de resolver todo el problema, como si se tratase de un proceso que hay que resolver. No existe tal.
Empieza siempre por separar los bloques de información que se indican, de modo que queden los conceptos simples. Esto quiere decir que primero debes ver que bloques de datos que intervienen en la consulta pueden ser obtenidos en consultas de menor complejidad.

Vamos a los problemas y las soluciones que planteas, para que se entienda la idea.

El primero dice así:
Cita:
Ciudades entre las que se haya programado el viaje de mayor duración junto con el vehículo y dni del conductor que lo hizo,
En este caso te piden tres cosas claras: a) Ciudades relacionadas con viajes; b) viaje más largos de todos, y c) conductores con sus DNI.

No pienses la consulta completa. Piensa cada parte de eso.

Voy a comenzar creando las tablas a partir de tu descripción pero las voy a normalizar un poco por necesidades de simpleza de consultas.

Código MySQL:
Ver original
  1. CREATE TABLE CONDUCTOR(
  2.     NOMBRE VARCHAR (30) NOT NULL,
  3.     DIREC VARCHAR (150) NOT NULL,
  4.     PROV_ID INT UNSIGNED NOT NULL);
  5. CREATE TABLE VEHICULO(
  6.     MATRICULA VARCHAR(10) NOT NULL PRIMARY KEY,
  7.     CARGAMAX MEDIUMINT UNSIGNED NOT NULL,
  8.     FECHACOMPRA DATE NOT NULL);
  9.     RUTA_ID INT UNSIGNED NOT NULL PRIMARY KEY,
  10.     CIUDADSAL_ID MEDIUMINT UNSIGNED NOT NULL,
  11.     CIUDADLLEG_ID MEDIUMINT UNSIGNED NOT NULL,
  12.     KM DECIMAL (14,2) NOT NULL);
  13. CREATE TABLE VIAJE_PROGRAMADO(
  14.     VIAJE_ID INT UNSIGNED NOT NULL PRIMARY KEY,
  15.     RUTA_ID INT UNSIGNED NOT NULL,
  16.     FECHASAL DATE NOT NULL,
  17.     HORASAL TIME NOT NULL,
  18.     FECHALLEG DATE NOT NULL,
  19.     HORALLEG TIME NOT NULL);
  20. CREATE TABLE VIAJE_ASIGNADO(
  21.     VIAJE_ID INT UNSIGNED NOT NULL,
  22.     DNI INT UNSIGNED NOT NULL,
  23.     MATRICULA VARCHAR(10),
  24.     PRIMARY KEY(VIAJE_ID, DNI, MATRICULA));
  25.  
  26. # Tablas de uso recomendado.
  27. CREATE TABLE CIUDAD(
  28.     CIUDAD_ID INT UNSIGNED NOT NULL PRIMARY KEY,
  29.     PROV_ID INT UNSIGNED NOT NULL,
  30.     NOMBRE_CIUDAD VARCHAR(150) NOT NULL);
  31.  
  32. CREATE TABLE PROVINCIA(
  33.     PROV_ID INT UNSIGNED NOT NULL PRIMARY KEY,
  34.     NOMBRE_CIUDAD VARCHAR(150) NOT NULL);
No uses "#" para los nombres de objetos, es el caracter de remark o comentario y puede causar problemas en algun momento.

Caso 1) Ciudades entre las que se haya programado el viaje de mayor duración junto con el vehículo y dni del conductor que lo hizo,

Veamos lo simple: viajes de mayor duración:
Código MySQL:
Ver original
  1. SELECT viaje_id
  2.     SELECT
  3.         viaje_id,
  4.         (TIMESTAMPDIFF(MINUTE, adddate(fechasal, horasal), adddate(fechalleg, horalleg))) duracion
  5.     FROM VIAJE_ASIGNADO) viajes
  6. HAVING duracion = MAX(duracion);
En principio el having debería funcionar bien en mi experiencia, pero hay otras formas de escribir esa consulta, aunque algo más complejas.
Luego vamos a las egunda parte: Viaje asignado, con su chofer y ciudad.

Código MySQL:
Ver original
  1. SELECT VP.viaje_id, CO.dni DocConductor, CO.nombre NombreConductor, C1.nombre Origen, C2.nombre Destino
  2. FROM viaje_asignado VA
  3.     INNER JOIN viaje_programado VP ON VA.viaje_id = VP.viaje_id
  4.     INNER JOIN ruta R ON VP.ruta_id = R.ruta_id
  5.     INNER JOIN ciudad C1 ON R.ciudad_sal = C1.ciudad_id
  6.     INNER JOIN ciudad C2 ON R.ciudad_lleg = C2.ciudad_id
  7.     INNER JOIN conductor CO ON VA.dni = CO.dni;
Es una consulta algo compleja como primer ejercicio de SQL, eso te lo concedo. Quien te lo dio así está un poco alterado de las neuronas.

A esto hay que agregarle el filtrado anterior:

Código MySQL:
Ver original
  1. WHERE VP.iaje_id IN (SELECT viaje_id
  2.                     FROM (
  3.                     SELECT
  4.                             viaje_id,
  5.                             (TIMESTAMPDIFF(MINUTE, adddate(fechasal, horasal), adddate(fechalleg, horalleg))) duracion
  6.                         FROM VIAJE_ASIGNADO) viajes
  7.                     HAVING duracion = MAX(duracion));

Con lo que al final podría funcionar así:

Código MySQL:
Ver original
  1. SELECT VP.viaje_id, CO.dni DocConductor, CO.nombre NombreConductor, C1.nombre Origen, C2.nombre Destino
  2. FROM viaje_asignado VA
  3.     INNER JOIN viaje_programado VP ON VA.viaje_id = VP.viaje_id
  4.     INNER JOIN ruta R ON VP.ruta_id = R.ruta_id
  5.     INNER JOIN ciudad C1 ON R.ciudad_sal = C1.ciudad_id
  6.     INNER JOIN ciudad C2 ON R.ciudad_lleg = C2.ciudad_id
  7.     INNER JOIN conductor CO ON VA.dni = CO.dni
  8. WHERE VP.iaje_id IN (SELECT viaje_id
  9.                     FROM (
  10.                     SELECT
  11.                             viaje_id,
  12.                             (TIMESTAMPDIFF(MINUTE, adddate(fechasal, horasal), adddate(fechalleg, horalleg))) duracion
  13.                         FROM VIAJE_ASIGNADO) viajes
  14.                     HAVING duracion = MAX(duracion));

Para mi es un ejercicio algo complicado para iniciarse...

Luego vemos el resto.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Última edición por gnzsoloyo; 31/01/2015 a las 16:21