2012-07-11 5 views
0

J'ai 2 tablesMysql requête (où et groupe)

tbl_activities

id | activity 
1 | activity1 
2 | activity2 

tbl_sub_activities

id |activityId | subActivity | status 
1 | 1   | subActivity1 | done 
2 | 1   | subActivity2 | done 
3 | 1   | subActivity3 | ongoing 
4 | 2   | subActivity4 | done 
5 | 2   | subActivity5 | done 

Scénario: Une activité peut avoir plusieurs sous-activités.

si l'état de la sous-activité est terminé, alors l'activité est terminée, si l'état de la sous-activité est toujours en cours, l'activité est en cours.

Question: Comment puis-je demander à tbl_activities d'avoir une sortie comme celle-ci. J'ai fait cela en utilisant php mais je veux savoir comment faire cela en utilisant une requête SQL.

Répondre

3

Selon votre modèle, vous pouvez utiliser cette requête vraiment performant:

SELECT 
    a.id, 
    a.activity, 
    MAX(s.status) as status 
FROM tbl_activities a 
INNER JOIN tbl_sub_activities s ON s.activityId = a.id 
GROUP BY a.id; 

Mais méfiez-vous qu'il dépend modèle : MAX(statuts) va toujours donner ongoing sauf si tous les sous-activités sont done ;-)

Pour une requête moins dépendante du modèle que vous pouvez considérer ce modèle:

SELECT 
    a.id, 
    a.activity, 
    SUM(s.status = "ongoing") as NB_ONGOING, 
    SUM(s.status = "done") as NB_DONE 
FROM tbl_activities a 
INNER JOIN tbl_sub_activities s ON s.activityId = a.id 
GROUP BY a.id; 
+0

Vous pouvez inclure '' a.activity' dans le GROUP BY' juste pour être plus de normes adhérentes. En outre, 'statuts' est mal orthographié. En dehors de ces choses, ça a l'air génial. –

+0

Ups, merci pour l'orthographe Zane :) En ce qui concerne le 'a.activity' dans le' GROUP BY', je suis totalement d'accord avec la norme mais je déteste toujours le faire car je n'ai pas encore évalué le problème de performance:/ –

+0

@Zane: Il existe des normes et des standards. –

1

si vous avez seulement deux fait état et continue ensuite cette requête peut fonctionne pour vous

Select a.id,a.activityid,b.status 
    from tbl_activities a 
    inner join tbl_sub_activities b on a.id=b.activityid 
    Group by a.id order by b.status DESC 
1

Pour mieux:

SELECT 
    a.id, 
    a.activity, 
    case when SUM(s.status = "done") = count(s.status) 
     then "DONE" else "ONGOING" 
    END 
FROM tbl_activities a 
INNER JOIN tbl_sub_activities s ON s.activityId = a.id 
GROUP BY a.id; 
+0

J'utiliserais un 'IF' moins verbeux au lieu de' CASE' ici. Et je ne suis pas vraiment sûr que ton état soit bon. Vous avez probablement cherché 'SUM (s.status =" done ") = COUNT (*)' –

+0

okay .. vous pouvez utiliser 'IF' :) Fixé il. Merci mon pote !! – manurajhada