El jue, 07-09-2006 a las 11:11 -0500, SANCHEZ Bejar Jorge escribió: > Amigos, disculpen por el OFFTOPIC. Un servicio tengo las siguientes tablas : > > Alumnoanho registra los años de estudios del alumno > CodAlumno anho seccion > 01 2004 6B > 01 2005 2C > 01 2006 1A > > > AlumnoanhoCurso registra los cursos que ha seguido por cada año > CodAlumno anho CodCurso nota > 01 2004 01 15 > 01 2005 01 20 > 01 2006 01 13 > 01 2004 11 16 > > > Y quiero generar el siguiente Reporte: > Alumno curso 2004 2005 2006 --> Los encabezados de las > columnas pueden cambiar según la tabla alumnoanho > 01 01 15 20 13 > 01 11 16 - - > > En la columna curso debe incluir todos los cursos seguidos durante los n años > y si no tiene nota para un año mostrar vacio o '-' > > Uso mysql 5 y php. Una manito con este query please. > > Saludos > > Jorge Bueno vamos con lo siguiente:
mysql> create table if not exists datosalumn(codal char(2) not null, anho char(4) not null, codcur char(2) not null, nota int not null, index (codal,anho,codcur)) engine=innodb; Query OK, 0 rows affected (0.05 sec) mysql> select * from datosalumn; +-------+------+--------+------+ | codal | anho | codcur | nota | +-------+------+--------+------+ | 1 | 2004 | 1 | 15 | | 1 | 2004 | 11 | 16 | | 1 | 2005 | 1 | 20 | | 1 | 2006 | 1 | 13 | +-------+------+--------+------+ 4 rows in set (0.00 sec) de lo solicitado tenemos que hay tres años, por un lado crear una solución ceñida a esos requerimientos es mas sencillo, caso contrario se requeriría crear la consulta en forma dinámica, mysql> select distinct anho from datosalumn; +------+ | anho | +------+ | 2004 | | 2005 | | 2006 | +------+ 3 rows in set (0.00 sec) de esta forma tenemos los años, que nos serian útiles para construir el string de la consulta dinámicamente, solo esbozo la idea, esa parte no la voy a desarrollar. mysql> create temporary table if not exists reporte2(codal char(2) not null,codcur char(2) not null, anho1 int not null, anho2 int not null, anho3 int not null, index(codal,codcur)) engine=memory; Query OK, 0 rows affected (0.00 sec) Se crea una tabla temporal en memoria para el soporte de datos del reporte, es importante señalar que la característica temporary permite a cada usuario generar la misma tabla sin entrar en conflictos con cualquier otro usuario que este haciendo la misma labor concurrentemente, incluso si hacen "show tables", verán que la tabla no sale listada. mysql> (select codal,codcur,nota,""as anho2,"" as anho3 from datosalumn where anho="2004") union (select codal,codcur,"" as anho1,nota,"" as anho3 from datosalumn where anho="2005") union (select codal,codcur,"" as anho1,"" as anho2,nota from datosalumn where anho="2006"); +-------+--------+------+-------+-------+ | codal | codcur | nota | anho2 | anho3 | +-------+--------+------+-------+-------+ | 1 | 1 | 15 | | | | 1 | 11 | 16 | | | | 1 | 1 | | 20 | | | 1 | 1 | | | 13 | +-------+--------+------+-------+-------+ 4 rows in set (0.00 sec) aprovecharemos de este select para insertarlo en la tabla temporal reporte, es necesario por la limitacion para aplicar agrupamiento sobre el resultado obtenido con union. mysql> insert into reporte2 (select codal,codcur,nota,""as anho2,"" as anho3 from datosalumn where anho="2004") union (select codal,codcur,"" as anho1,nota,"" as anho3 from datosalumn where anho="2005") union (select codal,codcur,"" as anho1,"" as anho2,nota from datosalumn where anho="2006"); Query OK, 4 rows affected, 8 warnings (0.00 sec) Records: 4 Duplicates: 0 Warnings: 8 mysql> select * from reporte; +-------+--------+-------+-------+-------+ | codal | codcur | anho1 | anho2 | anho3 | +-------+--------+-------+-------+-------+ | 1 | 1 | 15 | 0 | 0 | | 1 | 11 | 16 | 0 | 0 | | 1 | 1 | 0 | 20 | 0 | | 1 | 1 | 0 | 0 | 13 | +-------+--------+-------+-------+-------+ 4 rows in set (0.00 sec) esto es lo que se obtiene con un select simple. mysql> select codal,codcur,sum(anho1) as "2004",sum(anho2) as "2005" ,sum(anho3) as "2006" from reporte2 group by codal,codcur; +-------+--------+------+------+------+ | codal | codcur | 2004 | 2005 | 2006 | +-------+--------+------+------+------+ | 1 | 1 | 15 | 20 | 13 | | 1 | 11 | 16 | 0 | 0 | +-------+--------+------+------+------+ 2 rows in set (0.00 sec) se ha apelado al uso de sum() (funciones agregadas de dominio) por requerimientos del agrupamiento, pero como solo hay una nota por curso en cada año entonces no hay inconveniente, y como se ve no se requiere de ningún loop en php o cualquier otro lenguaje, lo que en el caso de tratarse de abundante data resultaría muy ineficiente. Saludos. FMAQ. > > _______________________________________________ > Lista de correo Linux-plug > Temática: Discusión general sobre Linux > Peruvian Linux User Group (http://www.linux.org.pe) > > Participa suscribiéndote y escribiendo a: [email protected] > Para darte de alta, de baja o hacer ajustes a tu suscripción visita: > http://www.linux.org.pe/cgi-bin/mailman/listinfo/linux-plug > > IMPORTANTE: Reglas y recomendaciones > http://www.linux.org.pe/listas/reglas.php > http://www.linux.org.pe/listas/comportamiento.php > http://www.linux.org.pe/listas/recomendaciones.php >
_______________________________________________ Lista de correo Linux-plug Temática: Discusión general sobre Linux Peruvian Linux User Group (http://www.linux.org.pe) Participa suscribiéndote y escribiendo a: [email protected] Para darte de alta, de baja o hacer ajustes a tu suscripción visita: http://www.linux.org.pe/cgi-bin/mailman/listinfo/linux-plug IMPORTANTE: Reglas y recomendaciones http://www.linux.org.pe/listas/reglas.php http://www.linux.org.pe/listas/comportamiento.php http://www.linux.org.pe/listas/recomendaciones.php
