2009-08-20 10 views
1

MISE À JOURInstruction SQL aide requise

Enfin réussi à travailler! Merci pour toute l'aide de tout le monde. Si vous remarquez des erreurs potentielles ou des possibilités d'amélioration dans ma requête, faites-le moi savoir.

SELECT * 
FROM TBL_CAMPAIGNS C 
INNER JOIN TBL_MEMBERS M 
    ON C.campaign_MemberId = M.members_Id 
INNER JOIN TBL_CAMPAIGNS_CHARITIES CC 
    ON C.campaign_Key = CC.camchar_CampaignID 
INNER JOIN TBL_CHARITIES CH 
    ON CC.camchar_CharityID = CH.cha_Key 
LEFT OUTER JOIN (
    select recip_Chosen, count(recip_CampaignId) as ChosenCount 
    from TBL_CAMPAIGNRECIPIENTS 
    WHERE recip_CampaignId = @campaign 
    group by recip_Chosen 
) CRC 
on CH.cha_Key = CRC.recip_Chosen 
WHERE C.campaign_Key = @campaign 

Merci !!!

///////////////////

Après quelques conseils vraiment utiles, j'ai décidé de mettre en œuvre la suggestion « orbMan comme suit;

SELECT * 
FROM TBL_CAMPAIGNS C 
INNER JOIN TBL_MEMBERS M 
    ON C.campaign_MemberId = M.members_Id 
INNER JOIN TBL_CAMPAIGNS_CHARITIES CC 
    ON C.campaign_Key = CC.camchar_CampaignID 
INNER JOIN TBL_CHARITIES CH 
    ON CC.camchar_CharityID = CH.cha_Key 
WHERE C.campaign_Key = @campaign 

Ceci renvoie une ligne pour chaque organisme associé à une campagne donnée (comme associé via TBL_Campaigns_Charities). Cependant, j'ai aussi une autre table (TBL_CAMPAIGNRECIPIENTS CR) qui détaille chaque personne invitée à participer à la campagne. En visitant la page de la campagne, ils peuvent sélectionner l'un des organismes de bienfaisance liés à la campagne.

Maintenant, j'ai besoin de savoir combien de personnes ont choisi chacune des organisations caritatives associées (CR.recip_Chosen). Leurs détails ne sont pas importants. J'ai juste besoin de savoir combien de personnes ont sélectionné chacune des organisations caritatives associées.

Donc quelque chose comme;

COUNT CH.cha_Key, FROM CR WHERE CR.recip_Chosen = CH.cha_Key 

mais intégré dans l'instruction ci-dessus.

Merci d'avance.

ORIGINAL POST-DESSOUS:

///////////////////

Salut,

j'ai besoin pour obtenir des données de sur 3 tables . Les deux premiers sont simples et sont actuellement saisis comme;

SELECT * FROM TBL_CAMPAIGNS C 
JOIN TBL_MEMBERS M 
ON C.campaign_MemberId = M.members_Id 
WHERE C.campaign_Key = @campaign 

La table 'TBL_CAMPAIGNS' contient plusieurs colonnes, dont cinq détiennent un int. Cet entier fait référence à la clé de la 3ème table 'TBL_CHARITIES'. Comment puis-je retourner les données de la troisième table en combinaison avec ce qui précède?

J'ai créé ce qui suit jusqu'à présent;

SELECT * FROM TBL_CAMPAIGNS C 
JOIN TBL_MEMBERS M 
ON C.campaign_MemberId = M.members_Id 
JOIN TBL_CHARITIES CH 
ON CH.cha_Key = C.campaign_Char1 
WHERE C.campaign_Key = @campaign 

Mais, comme vous pouvez le constater, cela renvoie uniquement C.campaign_Char1. Qu'en est-il de C.campaign_Char2, C.campaign_Char3, C.campaign_Char4, C.campaign_Char5 ?????

J'ai essayé cela;

SELECT * FROM TBL_CAMPAIGNS C 
JOIN TBL_MEMBERS M 
ON C.campaign_MemberId = M.members_Id 
JOIN TBL_CHARITIES CH 
ON CH.cha_Key = C.campaign_Char1 
AND CH.cha_Key = C.campaign_Char2 
AND CH.cha_Key = C.campaign_Char3 
....... 
WHERE C.campaign_Key = @campaign 

Mais, bien sûr, cela ne fonctionne pas!

Une suggestion/aide?

Merci d'avance.

Répondre

3

Ceci est une conception dénormalisée et c'est pourquoi vous avez des difficultés à l'interroger. Ce serait plus simple si (à la place des colonnes campaign_Char1 à 5) vous aviez une table many-to-many entre TBL_CAMPAIGNS et TBL_CHARITIES. Par exemple, TBL_CAMPAIGNS_CHARITIES. Cela contiendrait un ID de campagne et un ID de charité.

Ensuite, votre requête serait:

SELECT * 
FROM TBL_CAMPAIGNS C 
INNER JOIN TBL_MEMBERS M 
    ON C.campaign_MemberId = M.members_Id 
INNER JOIN TBL_CAMPAIGNS_CHARITIES CC 
    ON C.campaign_Key = CC.CampaignID 
INNER JOIN TBL_CHARITIES CH 
    ON CC.CharityID = CH.cha_Key 
WHERE C.campaign_Key = @campaign 

Mise à jour:

SELECT * 
FROM TBL_CAMPAIGNS C 
INNER JOIN TBL_MEMBERS M 
    ON C.campaign_MemberId = M.members_Id 
INNER JOIN TBL_CAMPAIGNS_CHARITIES CC 
    ON C.campaign_Key = CC.camchar_CampaignID 
INNER JOIN TBL_CHARITIES CH 
    ON CC.camchar_CharityID = CH.cha_Key 
LEFT OUTER JOIN (
    select recip_Chosen, count(*) as ChosenCount 
    from TBL_CAMPAIGNRECIPIENTS 
    group by recip_Chosen 
) CRC 
on CH.cha_Key = CRC.recip_Chosen 
WHERE C.campaign_Key = @campaign 
+0

Je préfère fixer le design sur le rapport aussi, votez pour cela. – Lazarus

+0

Alors, TBL_CAMPAIGNS_CHARITIES contiendrait-il jusqu'à 5 lignes pour chaque campagne? – Munklefish

+0

I.e. une ligne pour chacune des associations caritatives potentielles (par exemple C.campaign_Char1 .... etc comme dans l'exemple ci-dessus)? – Munklefish

2

Nous pensons d'abord que vous devrez à nouveau rejoindre la table TBL_CHARITIES pour chaque référence que vous voulez donner.

SELECT * FROM TBL_CAMPAIGNS C 
JOIN TBL_MEMBERS M 
ON C.campaign_MemberId = M.members_Id 
JOIN TBL_CHARITIES CH1 
ON CH1.cha_Key = C.campaign_Char1 
JOIN TBL_CHARITIES CH2 
ON CH2.cha_Key = C.campaign_Char2 
JOIN TBL_CHARITIES CH3 
ON CH3.cha_Key = C.campaign_Char3 
JOIN TBL_CHARITIES CH4 
ON CH4.cha_Key = C.campaign_Char4 
JOIN TBL_CHARITIES CH5 
ON CH5.cha_Key = C.campaign_Char5 
WHERE C.campaign_Key = @campaign 

Je suis sûr que quelqu'un a une meilleure solution.

+0

Cool, qui fonctionne à condition qu'aucun des 'C.campaign_Char [X]' sont '0' ou n'avez pas un match dans les TBL_CHARITIES. Evidemment c'est une faute dans mon utilisation de JOIN. Des idées? – Munklefish

+0

S'il y a un potentiel d'avoir moins de 5 charités, vous aurez besoin de LEFT JOIN au lieu de INNER JOIN sur les 5 jointures à TBL_CHARITIES. –

+0

Pensez-y résolu avec LEFT JOIN. Merci. – Munklefish

1

expansion un peu @OrbMan, exécutez l'instruction SQL suivante pour montrer comment cela se joue. Il devrait vous montrer à quoi ressemblent les tables, y compris la table many-to-many @ camp2char.

set nocount on 
DECLARE @camp TABLE (
    ID int, 
    ID2 int, 
    primary key (id) 
) 
DECLARE @memb table (
ID int NOT NULL, 
primary key (id) 
) 
DECLARE @chars table (
ID int NOT NULL, 
primary key (id) 
) 
DECLARE @camp2char table (
ID1 int NOT NULL, 
ID3 int NOT NULL 
) 
insert into @memb (id) values(100); 
insert into @memb (id) values(200); 
insert into @memb (id) values(300); 
insert into @chars (id) VALUES(1000); 
insert into @chars (id) VALUES(2000); 
insert into @chars (id) VALUES(3000); 
insert into @chars (id) VALUES(4000); 
insert into @chars (id) VALUES(5000); 
insert into @camp (ID,ID2) VALUES(1,100); 
insert into @camp (ID,ID2) VALUES(2,300); 
insert into @camp2char (ID1,ID3) VALUES(1,1000); 
insert into @camp2char (ID1,ID3) VALUES(1,2000); 
insert into @camp2char (ID1,ID3) VALUES(1,3000); 
insert into @camp2char (ID1,ID3) VALUES(1,5000); 
insert into @camp2char (ID1,ID3) VALUES(2,2000); 

PRINT '@camp'; 
select * from @camp; 
PRINT '@memb'; 
select * from @memb; 
PRINT '@chars'; 
select * from @chars; 
PRINT '@camp2char'; 
select * from @camp2char; 

select c.ID 'camp.id', m.ID 'memb.id', ch.id 'char.id' from @camp c 
inner join @memb m 
on c.id2 = m.id 
inner join @camp2char c2ch 
on c.id = c2ch.id1 
inner join @chars ch 
on c2ch.id3 = ch.id 
where c.id=1 

Un effet de cette approche est que, au lieu d'une ligne résultante, votre nombre de lignes de résultat sera égal au nombre de lignes correspondantes de charité qui correspondent à la campagne cible.

L'avantage est que vous pouvez avoir un nombre illimité d'associations caritatives associées à un nombre quelconque de campagnes. De plus, si vous avez déjà plus d'un membre par campagne, vous devrez le normaliser de la même façon (avec une table camp2memb, par exemple).

Sortie d'un script exécuté sur SQL SVR 2005

@camp 
ID   ID2 
----------- ----------- 
1   100 
2   300 

@memb 
ID 
----------- 
100 
200 
300 

@chars 
ID 
----------- 
1000 
2000 
3000 
4000 
5000 

@camp2char 
ID1   ID3 
----------- ----------- 
1   1000 
1   2000 
1   3000 
1   5000 
2   2000 

camp.id  memb.id  char.id 
----------- ----------- ----------- 
1   100   1000 
1   100   2000 
1   100   3000 
1   100   5000 
+0

Il ne fait rien du tout. – Munklefish

+0

Bien sûr, ça fait * quelque chose *. :) Hmmm ... SQL Server 2000 ici (w/2005 Mgt Studio), alors peut-être que c'est tout. Je l'ai fait dans une fenêtre de requête définie pour afficher les résultats de texte, bien que les résultats de la grille fonctionne aussi. L'exécutez-vous dans une fenêtre de requête ou essayez-vous de le placer dans un proc stocké ou quelque chose? –

+0

en cours d'exécution sur SQL2005 via le logiciel de gestion dans une fenêtre de l'éditeur de script. Juste montre 5 tables vides. Si je mets les instructions PRINT après les instructions SELECT, il sort les 3 premières tables avec des données mais pas les deux dernières tables. – Munklefish