Как написать этот запрос с помощью объединений? - PullRequest
2 голосов
/ 06 мая 2010

У меня есть настольная кампания, в которой есть подробности отправленных писем.

campaign_table:    campaign_id  campaign_name flag
                         1          test1       1
                         2          test2       1
                         3          test3       0 

другая настольная кампания, в которой есть подробности кампании.

 campaign_activity:  campaign_id   is_clicked    is_opened  
                          1             0            1        
                          1             1            0        
                          2             0            1
                          2             1            0

Я хочу получить все кампании со значением флага 3 и количеством столбцов is_clicked со значением 1 и количеством столбцов со значением is_opened 1 в одном запросе.

ie.   campaign_id  campaign_name  numberofclicks  numberofopens
           1          test1            1                1
           2          test2            1                1

Я сделал это, используя подзапрос с запросом:

select c.campaign_id,c.campaign_name,
(SELECT count(campaign_id) from campaign_activity WHERE campaign_id=c.id AND is_clicked=1) as numberofclicks,
(SELECT count(campaign_id) from campaign_activity WHERE campaign_id=c.id AND is_clicked=1) as numberofopens
FROM
campaign c
WHERE c.flag=1

Но люди говорят, что использование подзапросов не является хорошим соглашением о кодировании, и вы должны использовать соединение вместо подзапросов. Но я не знаю, как получить тот же результат, используя соединение. Я проконсультировался с некоторыми из моих коллег, и они говорят, что в этой ситуации невозможно использовать join. Можно ли получить тот же результат, используя соединения? если да, пожалуйста, скажите мне, как.

Ответы [ 5 ]

4 голосов
/ 06 мая 2010

Это должно сработать. Замените INNER JOIN на LEFT OUTER JOIN, если вы хотите включить кампании, в которых нет активности.

SELECT
    c.Campaign_ID
    , c.Campaign_Name
    , SUM(CASE WHEN a.Is_Clicked = 1 THEN 1 ELSE 0 END) AS NumberOfClicks
    , SUM(CASE WHEN a.Is_Opened = 1 THEN 1 ELSE 0 END) AS NumberOfOpens
FROM 
    dbo.Campaign c
INNER JOIN
    dbo.Campaign_Activity a
ON  a.Campaign_ID = c.Campaign_ID
GROUP BY
    c.Campaign_ID
    , c.Campaign_Name
4 голосов
/ 06 мая 2010

Если предположить, что is_clicked и is_opened равны 1 или 0, это должно работать:

select c.campaign_id, c.campaign_name, sum(d.is_clicked), sum(d.is_opened)
from campaign c inner join campaign_activity d 
on c.campaign_id = d.campaign_id
where c.flag = 1
group by c.campaign_id, c.campaign_name

Нет подзапросов.

2 голосов
/ 06 мая 2010

Хм. То, что вы хотите, так просто, как это? Я не уверен, что правильно читаю вопрос ...

SELECT
  campaign_table.campaign_id, SUM(is_clicked), SUM(is_opened)
FROM
  campaign_table 
    INNER JOIN campaign_activity ON campaign_table.campaign_id = campaign_activity.campaign_id
WHERE
  campaign_table.flag = 1
GROUP BY 
  campaign_table.campaign_id

Обратите внимание, что при наличии ВНУТРЕННЕГО СОЕДИНЕНИЯ вы не увидите кампании, в которых нет ничего соответствующего в таблице campaign_activity. В этом случае вы должны использовать LEFT JOIN и преобразовать NULL в 0 в SUM, например, SUM (IFNULL (is_clicked, 0)).

0 голосов
/ 06 мая 2010

SQL в простейшей и наиболее надежной форме: (отформатирован для удобства чтения)

SELECT 
campaign_table.campaign_ID, campaign_table.campaign_name, Sum(campaign_activity.is_clicked) AS numberofclicks, Sum(campaign_activity.is_open) AS numberofopens

FROM 
campaign_table INNER JOIN campaign_activity ON campaign_table.campaign_ID = campaign_activity.campaign_ID

GROUP BY 
campaign_table.campaign_ID, campaign_table.campaign_name, campaign_table.flag

HAVING 
campaign_table.flag=1;
0 голосов
/ 06 мая 2010

Полагаю, это должно быть сделано:

select * from campaign_table inner join campaign_activity on campaign_table.id = campaign_activity.id where campaign_table.flag = 3 and campaign_activity.is_clicked = 1 and campaign_activity.is_opened = 1

Внимание: это не тестируется в реальной ситуации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...