2009-06-15 7 views
1

J'ai eu le même problème avec sql pendant un moment et comme je m'assieds pour écrire le même hack 'force brute' que j'utilise toujours, je pense qu'il doit y avoir un façon plus efficace de faire ce que je veux faire.mysql-php interrogeant une liste pour construire une table

J'ai des tableaux semblables à cela:

grades(gradeID, taskID, grade, username, date) 
tasks(taskID, task...) 
assignment(assignmentID, title...) 
assignment_tasks(assignmentID, taskID) 
assignment_students(assignmentID, username) 
students(username, forename...) 

les 5 dernières tables sont assez statiques, mis en place une fois la plupart du temps laissé seul. Pour la table des notes, un nouvel enregistrement est créé chaque fois qu'une nouvelle note est entrée pour une tâche.

Je veux produire un tableau récapitulatif pour une tâche, qui peut consister en 5 tâches, et chaque étudiant peut avoir un nombre quelconque de notes pour chaque tâche, la plus récente étant celle que je veux afficher dans la tâche. résumé. Ce que je ferais normalement est d'interroger une liste d'étudiants, et une liste de tâches d'affectation, puis de construire une boucle imbriquée géante pour chaque tâche pour chaque étudiant, en interrogeant la note la plus récente pour chacun, en supposant 30 étudiants, 5 tâches, soit 152 requêtes, ce qui m'a toujours frappé comme trop.

Je m'imagine (j'espère) J'ai une lacune horriblement embarrassante dans mes connaissances en SQL et il y a une façon beaucoup plus intelligente de le faire.

Edit: Merci pour la réponse - je travaille toujours sur la construction de la base de données réelle afin que je puisse le tester, mais je soupçonne que la réponse ci-dessous ne couvre pas les questions suivantes:

si un étudiant N'a pas tenté une tâche/affectation, il n'y aura pas d'entrées pour eux dans la table des notes mais ils doivent toujours apparaître dans le tableau récapitulatif avec une note par défaut pour chaque tâche ("u"). Je pense que ce peu le rend plus difficile.

Modifier à nouveau: J'ai la base de données d'embryons maintenant et cela fonctionne en ce que je reçois une liste des grades les plus récents avec des lacunes où il n'y a pas de note. Transposer cette liste fait maintenant l'objet de another question!

Répondre

1
SELECT tasks.*, students.*, 
     (
     SELECT grade 
     FROM grades 
     WHERE grades.task_id = tasks.task_id 
       AND grades.username = students.username 
     ORDER BY 
       date DESC 
     LIMIT 1 
     ) AS lastgrade 
FROM assignments a 
JOIN assignment_tasks at 
ON  at.assignmentID = a.assignmentID 
JOIN assignment_students ast 
ON  ast.assignmentID = a.assignmentID 
JOIN tasks 
ON  tasks.task_id = at.task_id 
JOIN students 
ON  students.username = ast.username 
Questions connexes