Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Problema Con Sql De 1 Tabla (https://www.clubdelphi.com/foros/showthread.php?t=88267)

darkamerico 12-05-2015 01:16:05

Problema Con Sql De 1 Tabla
 
Saludos amigos, no soy tan bueno en SQL, tengo una tabla con la siguiente estructura:

Código SQL [-]
CREATE TABLE `postulante_puntaje` (
  `id_postulantenota` int(11) NOT NULL,
  `idexamen_fk` int(11) DEFAULT NULL,
  `idescuela_fk` int(11) DEFAULT NULL,
  `cod_postulante` varchar(10) DEFAULT NULL,
  `dni` char(8) DEFAULT NULL,
  `puntaje` varchar(8) DEFAULT NULL,
  PRIMARY KEY (`id_postulantenota`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Esa tabla almacena los puntajes de los examenes que dan los alumnos del Centro Pre Universitario, normalmente para ingresar los alumnos rinden 4 examenes.

tomemos como ejemplo los siguientes registros:

Código SQL [-]
INSERT INTO `postulante_puntaje` VALUES ('1', '1', '5', '035751', '77393424', '36.4348');

Aqui dice por ejemplo que el alumno identificado con documento nacional de identidad (cedula o dni): 77393424, obtuve una calificacion de 36.4348 en el examen nro 1 (la segunda columna especifica el numero del examen, 1,2,3 o 4). Ahora bien, yo necesito un sql que arroje lo siguiente:

NRO DNI EXAMEN1 EXAMEN2 EXAMEN3 EXAMEN4 PROMEDIO

Agradezco infinitamente la ayuda que puedan brindarme.


Muchas Gracias

fjcg02 12-05-2015 14:15:29

hola,
puedes hacer varias cosas, pero siempre deberás agrupar po dni si quieres mostrarlo en una sola fila.

Supongo que usas mysql por la definición de la tabla, y no sé si soportará esto.

Opción A: sacar todo de la tabla
Opción B: hacer uniones con la tabla y consigo misma para extraer la información.

Para que veas cómo puedes hacerlo, y steniendo en cuenta que tu motor de sql puede variar algunas clausulas.
Código SQL [-]
select DNI, 
max( case idexamen_fk = 1 then puntaje else 0 end ) as EXAMEN_1,
max( case idexamen_fk = 2 then puntaje else 0 end ) as EXAMEN_2,
max( case idexamen_fk = 3 then puntaje else 0 end ) as EXAMEN_3,
max( case idexamen_fk = 4 then puntaje else 0 end ) as EXAMEN_4

FROM POSTULANTE_PUNTAJE

GROUP BY DNI

Podrías utilizar esta consulta para unirla con las demás tablas ( datos de usuario, nombre examen...)

El gran inconveniente es que si añades examenes, tendrías que cambiar la consulta.
Prueba y nos dices.

Espero que te haya ayudado.

Un saludo

Casimiro Notevi 12-05-2015 17:32:44

O usar un procedimiento almacenado en la base de datos.

fjcg02 12-05-2015 19:22:47

Cita:

Empezado por Casimiro Notevi (Mensaje 492067)
O usar un procedimiento almacenado en la base de datos.

También...

Saludos

darkamerico 12-05-2015 20:56:50

Saludos amigos
 
Después de mucho padecer, llegue a un sql como el siguiente:

Código SQL [-]
SELECT postulante_puntaje.dni, postulante_puntaje.idescuela_fk, postulante_puntaje.puntaje as p1,
(SELECT postulante_puntaje.puntaje
FROM postulante_puntaje
WHERE postulante_puntaje.idexamen_fk = 2 AND
      postulante_puntaje.dni = '74360500') as p2,
(SELECT postulante_puntaje.puntaje
 FROM postulante_puntaje
WHERE postulante_puntaje.idexamen_fk = 3 AND
      postulante_puntaje.dni = '74360500') as p3,
(SELECT postulante_puntaje.puntaje
FROM postulante_puntaje
WHERE postulante_puntaje.idexamen_fk = 4 AND
      postulante_puntaje.dni = '74360500') as p4
FROM postulante_puntaje
WHERE postulante_puntaje.idexamen_fk = 1 AND
      postulante_puntaje.dni = '74360500'

Quizas no sea la consulta mas inteligente que haya hecho, pero al menos funciona, si hubieran sugerencias para mejorarla, seria muy interesante.

Saludos

fjcg02 13-05-2015 08:58:28

Pero eso sólo saca los datos de una persona, no?

Saludos

bucanero 13-05-2015 10:26:50

Cita:

Empezado por darkamerico (Mensaje 492076)
Después de mucho padecer, llegue a un sql como el siguiente:

Código SQL [-]
SELECT postulante_puntaje.dni, postulante_puntaje.idescuela_fk, postulante_puntaje.puntaje as p1,
(SELECT postulante_puntaje.puntaje
FROM postulante_puntaje
WHERE postulante_puntaje.idexamen_fk = 2 AND
      postulante_puntaje.dni = '74360500') as p2,
(SELECT postulante_puntaje.puntaje
 FROM postulante_puntaje
WHERE postulante_puntaje.idexamen_fk = 3 AND
      postulante_puntaje.dni = '74360500') as p3,
(SELECT postulante_puntaje.puntaje
FROM postulante_puntaje
WHERE postulante_puntaje.idexamen_fk = 4 AND
      postulante_puntaje.dni = '74360500') as p4
FROM postulante_puntaje
WHERE postulante_puntaje.idexamen_fk = 1 AND
      postulante_puntaje.dni = '74360500'

Quizas no sea la consulta mas inteligente que haya hecho, pero al menos funciona, si hubieran sugerencias para mejorarla, seria muy interesante.

Saludos

una forma de simplificar, o por lo menos que sea un poco mas legible esta consulta podría ser esta:

Código SQL [-]
SELECT p1.dni, p1.idescuela_fk, p1.puntaje as p1, p2.puntaje, p3.puntaje, p4.puntaje
FROM postulante_puntaje p1
LEFT JOIN postulante_puntaje p2 ON p2.idexamen_fk = 2 and p2.dni = p1.dni and p2.idescuela_fk=p1.idescuela_fk
LEFT JOIN postulante_puntaje p3 ON p3.idexamen_fk = 3 and p3.dni = p1.dni and p3.idescuela_fk=p1.idescuela_fk
LEFT JOIN postulante_puntaje p4 ON p4.idexamen_fk = 4 and p4.dni = p1.dni and p4.idescuela_fk=p1.idescuela_fk
WHERE p1.idexamen_fk = 1 AND
      p1.dni = '74360500'

En principio si se garantiza que ya están insertadas las cuatro notas, en vez de realizar la agrupación de las tablas con LEFT JOIN se puede realizar con INNER JOIN y la consulta se ejecutara mas rápido en el servidor, pero si no es posible garantizar este punto, entonces se utilizara el LEFT JOIN o de lo contrario no devolverá los resultados que les falte alguna de las notas


saludos

darkamerico 13-05-2015 12:55:20

Gracias amigo
 
Gracias bucanero, la solucion que propones esta mejor que la mia, la tomare.

fjcg02 esa consulta sera parte de un programa en php donde cambiare el parametro duro dni por una variable, de forma que pueda recorrer toda una tabla de postulantes.


Gracias a todos por la atencion prestada.

;)


La franja horaria es GMT +2. Ahora son las 08:51:15.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi