2011-05-05 6 views
2

Je ne sais pas si cela peut être fait. Mais je voulais juste vérifier avec les experts ici.MySQL - Rejoindre une table deux fois avec une table principale

Mon cas est: J'ai un tbl_campaign de table qui stocke essentiellement une campagne qui a un à plusieurs relation avec une table appelée tbl_campaign_user où les utilisateurs qui ont été sélectionnés au cours de la campagne sont stockés avec l'identifiant de la campagne (tbl_campagin_user. cu_campaign_id = tbl_campaign.campaign_id).

La deuxième table (tbl_campaign_user) a un champ d'état qui est 0/1 indiquant non envoyé/envoyé. Je voulais écrire une seule requête sql qui lirait les données de la campagne ainsi que le nombre d'utilisateurs de la campagne envoyés et non envoyés (c'est pourquoi je rejoins deux fois sur la deuxième table). J'ai essayé ceci ci-dessous, mais j'ai le même nombre de comptes envoyés et non envoyés.

SELECT `tbl_campaign`.*, 
COUNT(sent.cu_id) as numsent, 
COUNT(unsent.cu_id) as num_unsent FROM (`tbl_campaign`) 

LEFT JOIN tbl_campaign_user as sent on (sent.cu_campaign_id = tbl_campaign.campaign_id and sent.cu_status='1') 

LEFT JOIN tbl_campaign_user as unsent on (unsent.cu_campaign_id = tbl_campaign.campaign_id and unsent.cu_status='0') 


WHERE `tbl_campaign`.`campaign_id` = '19' 

J'ai essayé le débogage en brisant la requête en deux parties: =>

SELECT `tbl_campaign`.*, 

COUNT(unsent.cu_id) as num_unsent FROM (`tbl_campaign`) 

Left join tbl_campaign_user as unsent on (unsent.cu_campaign_id = tbl_campaign.campaign_id and unsent.cu_status='0') 

WHERE `tbl_campaign`.`campaign_id` = '19' 

Les travaux ci-dessus exactement comme vous le souhaitez. Et tout comme le celui ci-dessous:

=>

SELECT `tbl_campaign`.*, 
COUNT(sent.cu_id) as numsent FROM (`tbl_campaign`) 

Left join tbl_campaign_user as sent on (sent.cu_campaign_id = tbl_campaign.campaign_id and sent.cu_status='1') 

WHERE `tbl_campaign`.`campaign_id` = '19' 

Je ne sais pas ce que j'ai fait mal lors de la fusion des deux. Je sais que je ne sais pas grand chose sur les jointures, donc peut-être une erreur conceptuelle? S'il vous plaît quelqu'un pourrait-il m'aider?

Merci d'avance!

Répondre

2

Vous n'avez besoin de joindre qu'une seule fois tbl_campaign_user et comptez (somme, peu importe) combien de fois cu_status était égal à zéro/un.

SELECT `tbl_campaign`.id, 
count(u.id) as num_all_campaign_users 
sum(u.cu_status) as num_sentcampaign_users, 
count(u.id) - sum(u.cu_status) as num_unsent_campaign_users 
FROM `tbl_campaign` c 
LEFT JOIN tbl_campaign_user as u on (u.cu_campaign_id = c.campaign_id) 
WHERE `tbl_campaign`.`campaign_id` = '19' 
group by `tbl_campaign`.id 

Notez que ceci est sorte de code pseudo, vous pouvez avoir à élaborer la somme/compte dans la clause select et le groupe par article ainsi.

+0

Salut bpgergo, merci pour votre réponse rapide. J'ai changé le groupe en tbl_campaign.campaign_id et j'ai corrigé la condition ON pour user.cu_campaign_id au lieu de unsent.cu ... (Je sais que c'était une faute de frappe de votre part, mais juste au cas où quelqu'un voudrait utiliser sur un similaire occassion). Cependant, ce que je cherche est un aperçu relatif des jointures - que se passe-t-il si ma table n'a pas de cu_status et qu'aucune somme n'est possible? Je voudrais plus d'aide à ce sujet :) – zarun

+0

Ajouter :: Est-ce que LEFT JOINing deux sous-requêtes serait la seule option dans ce cas? – zarun

+0

Si votre champ tbl_campaign_user.cu_status n'avait pas de valeurs possibles de zéro et un mais des drapeaux de caractères, alors votre somme serait quelque chose comme ceci: 'sum (if (cu_status = 'S', 1, 0))' Voir mysql [if ] (http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html#function_if). Dans un tel cas, SUM est votre ami: vous devez trouver une fonction qui donne 1 pour les cas souhaités et zéro pour tous les autres et ensuite utiliser SUM pour compter les cas souhaités. J'espère que ça aide. – bpgergo

Questions connexes