如何使用连接编写此查询?

时间:2010-05-06 08:57:32

标签: sql mysql database

我有一个表格广告系列,其中包含已发送的广告系列邮件的详细信息。

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的所有广告系列和值为1的is_clicked列数以及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 个答案:

答案 0 :(得分:4)

假设is_clickedis_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

没有子查询。

答案 1 :(得分:4)

这应该可以解决问题。如果要包含没有活动的广告系列,请将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

答案 2 :(得分:2)

嗯。你想要的只是这么简单吗?我不确定我正在读这个问题......

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

请注意,在此处使用INNER JOIN,您将看不到campaign_activity表中没有任何内容对应的广告系列。在这种情况下,您应该使用LEFT JOIN,并在SUM中将NULL转换为0,例如SUM(IFNULL(is_clicked,0))。

答案 3 :(得分:0)

我想这应该这样做:

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

Attn:这不是在现场测试

答案 4 :(得分:0)

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;