2009-01-22 24 views
1

J'ai une base de données MySql avec trois tables que j'ai besoin de combiner dans une requête: schedule, inscrits et waitlist. Ils mettent en œuvre un système d'inscription de base.Comment inclure des rowcounts filtrés provenant de deux autres tables dans une requête d'un tiers?

La planification contient les classes planifiées. Lorsqu'un utilisateur s'inscrit dans une classe, son ID de compte d'utilisateur et l'ID de la classe planifiée sont stockés dans l'inscription. Si une classe est à capacité, ils sont stockés dans la liste d'attente à la place. Les trois tables partagent une colonne scheduleId qui identifie chaque classe. Lorsque j'interroge la table de nomenclature, je dois également renvoyer les colonnes inscrites et liste d'attente qui représentent le nombre d'utilisateurs inscrits et en attente de ce planningId particulier.

Une requête préliminaire, je suis venu avec pour y parvenir est:

select s.id, s.classDate, s.instructor, COUNT(e.id) as enrolled 
from schedule as s 
left outer join enrolled as e 
on s.id = e.scheduleId 
group by s.id 

qui fonctionne bien pour l'un ou l'autre, mais il est évident que je ne peux pas obtenir les valeurs pour les deux inscrits et des tables de liste d'attente de cette façon . Quelqu'un peut-il suggérer un bon moyen de le faire?

Répondre

3

je le ferais avec une autre jointure gauche et le compte de deux roues alignées (concepts distincts)

select s.id, s.classDate, s.instructor , 
count(distinct e.id) as enrolled, 
count(distinct w.id) as waiting 
from schedule as s 
left outer join enrolled as e 
on s.id = e.scheduleID 
left outer join waitlist as w 
on s.id = w.scheduleID 
group by s.id 

Lorsque j'ai exécuté cette approche par rapport aux sous-requêtes, elle s'est exécutée environ deux fois plus vite, mais je regarde un jeu de résultats assez petit.

0

Deux façons rapides:

1- Utilisez COUNT(DISTINCT e.id), COUNT(DISTINCT w.id) pour obtenir le nombre de cas uniques dans chaque tableau, puis se joindre à la fois. C'est peut-être hideusement inefficace.

2- Utilisez les sous-requêtes dans la clause FROM (ne fonctionne que dans MySQL 5.0 et versions ultérieures):

SELECT s.id, s.classDate, s.instructor, tmpE.c AS enrolled, tmpW.c AS waiting 
FROM 
    schedule AS s, 
    (SELECT scheduleID, COUNT(*) AS c FROM enrolled GROUP BY scheduleID) AS tmpE, 
    (SELECT scheduleID, COUNT(*) AS c FROM waiting GROUP BY scheduleID) AS tmpW 
WHERE 
    s.id = e.scheduleID 
    AND s.id = w.scheduleID 
GROUP BY s.id 

j'ai raté une jointure gauche là-bas, cependant.

4

Utilisez les requêtes SELECT imbriquées. En supposant un peu de votre schéma, que diriez-vous quelque chose comme ça (ne fonctionne pas sur certaines saveurs de SQL):

select s.id, s.classDate, s.instructor, 
     (select COUNT(e.id) from enrolled e where e.scheduleId = s.id) as enrolled, 
     (select COUNT(w.id) from waitlist w where w.scheduleId = s.id) as waiting 
from schedule as s 
group by s.id 
Questions connexes