Требуется помощь оператора SQL - PullRequest
1 голос
/ 20 августа 2009

UPDATE

Наконец-то удалось разобраться! Спасибо всем за помощь. Если вы обнаружите какие-либо потенциальные ошибки или возможности для улучшения в моем запросе, пожалуйста, сообщите мне.

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

Спасибо !!!

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

После некоторых действительно полезных советов я решил реализовать предложение orbMan следующим образом:

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

Возвращает 1 строку для каждой благотворительной организации, связанной с данной кампанией (как связано с TBL_Campaigns_Charities). Тем не менее, у меня также есть другая таблица (TBL_CAMPAIGNRECIPIENTS CR), в которой подробно описывается каждый человек, приглашенный принять участие в кампании. Посетив страницу кампании, они могут выбрать одну из благотворительных организаций, связанных с кампанией.

Теперь мне нужно знать, сколько людей выбрали каждую из связанных благотворительных организаций (CR.recip_Chosen). Их детали не важны. Мне просто нужно знать, сколько людей выбрали каждую из связанных благотворительных организаций.

Так что-то вроде;

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

но интегрировано в приведенное выше утверждение.

Заранее спасибо.

ОРИГИНАЛЬНЫЙ ПОЧТ НИЖЕ:

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

Привет

Мне нужно получить данные из трех таблиц. Первые два являются прямыми и в настоящее время считаются как;

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

Таблица TBL_CAMPAIGNS содержит различные столбцы, пять из которых содержат int. Это int относится к ключу 3-ей таблицы 'TBL_CHARITIES'. Как мне вернуть данные третьей таблицы в сочетании с вышеприведенным?

Я создал следующее:

 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

Но, как вы можете сказать, это возвращает только C.campaign_Char1. А как насчет C.campaign_Char2, C.campaign_Char3, C.campaign_Char4, C.campaign_Char5 ?????

Я попробовал это;

 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

Но, конечно, это не работает!

Любые предложения / помощь?

Заранее спасибо.

Ответы [ 3 ]

3 голосов
/ 20 августа 2009

Это денормализованный дизайн, и поэтому вам трудно его опрашивать. Было бы проще, если бы (вместо столбцов campaign_Char1-5) у вас была таблица «многие ко многим» между TBL_CAMPAIGNS и TBL_CHARITIES. Например, TBL_CAMPAIGNS_CHARITIES. Это будет содержать идентификатор кампании и CharityID.

Тогда ваш запрос будет:

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

Обновление:

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
2 голосов
/ 20 августа 2009

Первая мысль: вам придется снова присоединиться к таблице TBL_CHARITIES для каждой ссылки, которую вы хотите дать.

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

Я уверен, что у кого-то есть лучшее решение.

1 голос
/ 20 августа 2009

Немного расширив @OrbMan, запустите следующий SQL, чтобы продемонстрировать, как это работает. Он должен показать вам, как выглядят таблицы, включая таблицу 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

Одним из эффектов этого подхода является то, что вместо одной результирующей строки количество ваших строк результатов будет равно числу подходящих строк благотворительности, соответствующих целевой кампании.

Преимущество заключается в том, что вы можете иметь любое количество благотворительных организаций, связанных с любым количеством кампаний.

Кроме того, если у вас есть более одного участника в кампании, вы хотите нормализовать его таким же образом (например, с таблицей camp2memb).

Вывод из скрипта, запущенного на 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
...