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

Recuperar lista con campo que sea un SELECT de otra tabla

Estas en el tema de Recuperar lista con campo que sea un SELECT de otra tabla en el foro de Mysql en Foros del Web. Hola a todos, quería pedir ayuda o consejo sobre una sentencia SQL bastante complicada que me ha tocado construir y realmente no sé cómo resolverla. ...
  #1 (permalink)  
Antiguo 08/05/2009, 11:08
Avatar de Seixas  
Fecha de Ingreso: mayo-2004
Ubicación: Barcelona
Mensajes: 60
Antigüedad: 15 años, 1 mes
Puntos: 0
Pregunta Recuperar lista con campo que sea un SELECT de otra tabla

Hola a todos,

quería pedir ayuda o consejo sobre una sentencia SQL bastante complicada que me ha tocado construir y realmente no sé cómo resolverla. El caso real es bastante lioso y usa muchas tablas, así que expongo una versión simplificada.

Las tablas que tengo son:

Alumnos (nif, nombre)
Pruebas (id, asignatura)
Examenes (alumno, prueba, evaluado, nota) donde alumno y prueba son claves foráneas

Es por tanto, una relación N:M donde Examenes es la tabla de relación.

Pues bien, lo que quiero hacer es una consulta que me devuelva todos los estudiantes con su nif, nombre y un campo con el número de exámenes que tiene pendientes de ser evaluados (evaluado a FALSE).

La consulta que hasta ahora he construido es esta:

SELECT Al.*, (SELECT COUNT(prueba) FROM Examenes WHERE evaluado = FALSE AND alumno = Al.nif) AS pendientes FROM Alumnos Al;

El problema que me encuentro es que dentro de la subconsulta para el campo "pendientes" no sabe identificar para cada uno de los alumnos de la tabla, es decir, Al.nif no lo entiende. ¿Hay alguna manera de solventar esto?

¿Alguien lo haría de otra manera?

Mi idea sería conseguirlo sin tener que hacer nuevos campos en la tabla alumno, siempre que fuera posible.

Gracias por cualquier sugerencia que me podais hacer.
  #2 (permalink)  
Antiguo 08/05/2009, 11:46
 
Fecha de Ingreso: septiembre-2008
Ubicación: Cuernavaca, Morelos
Mensajes: 40
Antigüedad: 10 años, 8 meses
Puntos: 0
Respuesta: Recuperar lista con campo que sea un SELECT de otra tabla

creo que solo te falta definir la tabla de alumnos dentro de el select de pendientes
  #3 (permalink)  
Antiguo 08/05/2009, 11:52
Avatar de alguienmas  
Fecha de Ingreso: mayo-2009
Mensajes: 62
Antigüedad: 10 años, 1 mes
Puntos: 8
Respuesta: Recuperar lista con campo que sea un SELECT de otra tabla

Cita:
Iniciado por Seixas Ver Mensaje
Las tablas que tengo son:

Alumnos (nif, nombre)
Pruebas (id, asignatura)
Examenes (alumno, prueba, evaluado, nota) donde alumno y prueba son claves foráneas

SELECT Al.*, (SELECT COUNT(prueba) FROM Examenes WHERE evaluado = FALSE AND alumno = Al.nif) AS pendientes FROM Alumnos Al;
yo lo hari asi:

SELECT a.nif, a.nombre, count(e.prueba) as pendiente FROM (alumnos as a JOIN examenes as e ON a.nif = e.alumno) WHERE e.evaluado=false;

o asi que es lo mismo:

SELECT a.nif, a.nombre, count(e.prueba) as pendiente FROM alumnos as a, examenes as e WHERE e.evaluado=false AND e.alumno = a.nif;

Espero esten buenas las consultas, pues las hice al vuelo, pero como informacion te dejo estos enlaces de como funcionan los JOIN:

es_wikipedia_org/wiki/Join
dev_mysql_com/doc/refman/5.0/es/join.html

(cambia los _ por . ya que aun no me deja poner enlaces en el foro)

Saludos
  #4 (permalink)  
Antiguo 08/05/2009, 12:33
Avatar de Seixas  
Fecha de Ingreso: mayo-2004
Ubicación: Barcelona
Mensajes: 60
Antigüedad: 15 años, 1 mes
Puntos: 0
Respuesta: Recuperar lista con campo que sea un SELECT de otra tabla

Gracias, antes que nada, por vuestras respuestas.

limonchaz, imagino que te referías a hacer algo así:

Código PHP:
SELECT Al.*, (SELECT COUNT(pruebaFROM ExamenesAlumnos A WHERE evaluado FALSE AND alumno A.nif) AS pendientes FROM Alumnos Al

He probado lo que me comentas, pero creo que no es la solución. El campo pendientes contiene el mismo valor para todos los alumnos que recupero. Creo que así lo que hace la subconsulta es asignar al valor pendientes todos los examenes que no han sido evaluados.


alguienmas, he probado lo que me comentas, pero tampoco parece funcionar, aunque ha estado cerca. Al cambiar la sentencia me ha devuelto el siguiente error...

Cita:
Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause'
... pero lo he solventado haciendo un GROUP BY a.nif.
Una vez así, como resultado me duelve todos los alumnos que tienen algún exámen por evaluar, pero yo quiero tener todos los alumnos.

Gracias de nuevo por la ayuda.

¿Alguna otra idea?
  #5 (permalink)  
Antiguo 08/05/2009, 12:35
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 11 años, 2 meses
Puntos: 300
Respuesta: Recuperar lista con campo que sea un SELECT de otra tabla

No la he probado

Código sql:
Ver original
  1. SELECT alumnos.nif, alumnos.nombre, t1.total totalpendientes
  2.   FROM alumnos INNER JOIN
  3.     (SELECT alumno, COUNT(*) total FROM examenes
  4.       WHERE evaluado = FALSE GROUP BY alumno HAVING total >=1 )t1
  5.          ON alumnos.nif = t1.alumno ORDER BY alumnos.nombre

Última edición por jurena; 08/05/2009 a las 12:40
  #6 (permalink)  
Antiguo 11/05/2009, 02:21
Avatar de Seixas  
Fecha de Ingreso: mayo-2004
Ubicación: Barcelona
Mensajes: 60
Antigüedad: 15 años, 1 mes
Puntos: 0
De acuerdo Respuesta: Recuperar lista con campo que sea un SELECT de otra tabla

jurena, mil gracias. Has dado con la solución.

He tenido que cambiar el INNER JOIN por LEFT JOIN y ha funcionado perfecto.

No sabía que se podían hacer JOINs con subconsultas. Esa era la clave que me faltaba.

Gracias de nuevo. Un saludo a todos.
  #7 (permalink)  
Antiguo 11/05/2009, 04:24
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 11 años, 2 meses
Puntos: 300
Respuesta: Recuperar lista con campo que sea un SELECT de otra tabla

Es cierto, Seixas,
si querías tener todos los alumnos, tenías que usar el LEFT JOIN, pero cuando salga null, tendrás que usar IFNULL o COALESCE, algo así en el SELECT primero:
select ... IFNULL(t1.total totalpendientes, 'no tiene pendientes')

Saludos.
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:34.