mysql正确加入group by问题

时间:2010-07-28 13:10:27

标签: mysql join group-by

我有两张桌子:

  1. LandingPages - 包含每个广告系列的目标网页。

  2. 报告 - 包含每个目标网页的匹配和转化。

  3. 我尝试进行查询,为每个着陆页带来点击和转化的总和,

    但是我希望如果目标网页没有收到任何点击和转化( 而不是在报告表 中显示),那么我希望返回0作为结果。< / p>

    我现在所做的是:

    SELECT l.LandingPageId, SUM(Hits) AS Hits, SUM(PixelSum) AS Conversion 
    FROM Report c
    RIGHT JOIN LandingPages l ON(c.LandingPageId = l.LandingPageId )
    WHERE c.CampaignId = x  
    AND DayDate > 'y'
    GROUP BY c.LandingPageId
    

    问题是我只获得报告表中存在着陆页的行并传递日期'y',

    (例如:我只获得2行着陆页,但有4个着陆页

    如果我运行此查询,我会得到4个结果

    SELECT l.LandingPageId FROM LandingPages l WHERE l.CampaignId = x 
    

    不是所有目标网页(0值),

    我怎样才能让这个像我想要的那样工作,给我一个不在报告表或表格中但不是在旧日期的登陆页面?

    感谢。

    更新:

    我得到了很多答案,我得到的部分解决方案只有在报告表中根本不存在着陆页时才能为我工作,但如果它存在但日期条款不匹配则不会出现:

    部分解决方案查询:

     SELECT l.LandingPageId, IFNULL(SUM(Hits),0) AS Hits, IFNULL(SUM(PixelSum),0)  AS Conversion
        FROM LandingPages l
        LEFT JOIN Report c  ON( l.LandingPageId = c.LandingPageId) 
        WHERE (l.CampaignId = x OR  l.CampaignId IS NULL) 
        AND (DayDate > 'y' OR DayDate IS NULL)
        GROUP BY l.LandingPageId
    

    我仍然需要你的帮助!

    谢谢!

6 个答案:

答案 0 :(得分:3)

好。当我运行以下内容时,我从下面得到结果。这就是你想要的吗?

drop table landingpages;
create table landingpages (campaignid number, landingpageid number,  daydate number);

insert into landingpages values (1,100,20);
insert into landingpages values (1,101,21);
insert into landingpages values (2,102,20);
insert into landingpages values (2,103,21);

drop table report;
create table report (campaignid number, landingpageid number, hits number, pixelsum number);

insert into report values (1,100, 2, 1 );
insert into report values (2,102, 20, 21 );
insert into report values (2,103, 30, 31 );

commit;

SELECT c.LandingPageId, SUM(Hits) AS Hits, SUM(PixelSum) AS Conversion  
    FROM landingpages c 
    LEFT JOIN report l ON(c.LandingPageId = l.LandingPageId ) 
    WHERE c.CampaignId = 1   
    AND DayDate > 19 
    GROUP BY c.LandingPageId 


LANDINGPAGEID       HITS CONVERSION
------------- ---------- ----------
          100          2          1
          101                      


2 rows selected.

我希望这就是你所需要的。我在Oracle上运行了上述内容,但它在mySQL中应该没有什么区别,因为这是所有标准查询语言。

答案 1 :(得分:2)

首先,您没有告诉我们存储了哪个表HitsPixelSumDayDate?在我的查询中表示了这一事实。显然,?需要替换为正确的别名。但是,我假设DayDate来自报告表,因为如果日期标准不匹配,您后来提到了问题。

简而言之,您需要在Left Join的ON子句中应用该条件。在连接到LandingPages表之前,将应用ON子句条件。因此,广告系列&lt;&gt;除了DayDate值&lt; ='y'(顺便说一句,DayDate的数据类型是什么?DayDate > 'y'对我来说是可疑的)之前,X将被过滤掉。然后加入LandingPages表。

此外,您应该考虑使用Coalesce代替IsNull,因为Coalesce是ISO标准。

Select L.LandingPageId
    , Coalesce( Sum( ?.Hits ), 0 ) As Hits
    , Coalesce( Sum( ?.PixelSum ), 0 ) As Conversion
From LandingPages As L
    Left Join Report As R
        On R.LandingPageId = L.LandingPageId
            And R.CampaignId = X
            And ( R.DayDate > 'y' Or R.DayDate Is Null )
Group By L.LandingPageId

For more information on Left Joins, here is a visual representation

答案 2 :(得分:1)

这是RIGHT JOIN的b / c。重新运行为:

SELECT l.LandingPageId, SUM(Hits) AS Hits, SUM(PixelSum) AS Conversion 
FROM LandingPages l
LEFT JOIN Reports c ON(c.LandingPageId = l.LandingPageId )
WHERE c.CampaignId = x  
AND DayDate > 'y'
GROUP BY c.LandingPageId

答案 3 :(得分:1)

您拥有:WHERE c.CampaignId = x这意味着如果目标网页未收到任何点击和转化(并且未在报告表格中显示),则即使您使用正确,目标网页也不会显示在结果中加入。那些着陆页的c.CampaignId为空,c.CampaignId = x将为false。

尝试:

SELECT l.LandingPageId, SUM(Hits) AS Hits, SUM(PixelSum) AS Conversion 
FROM Report c
RIGHT JOIN LandingPages l ON(c.LandingPageId = l.LandingPageId )
WHERE (c.CampaignId = x  or c.CampaignId is null)  
AND DayDate > 'y'
GROUP BY l.LandingPageId

我也按l.LandingPageId分组,因为对于没有报告的登陆页面,c.LandingPageId为空。

答案 4 :(得分:1)

我采取托马斯的想法,  而且几乎没有改善它的工作!

查询:

Select L.LandingPageId
    , Coalesce( Sum( R.Hits ), 0 ) As Hits
    , Coalesce( Sum( R.PixelSum ), 0 ) As Conversion
From LandingPages As L
    Left Join Report As R
        On R.LandingPageId = L.LandingPageId
            And L.CampaignId = X
            And R.DayDate > 'y' 
WHERE L.CampaignId = X
Group By L.LandingPageId

答案 5 :(得分:0)

我看到的一些问题......

  • 请在所有情况下为您的列添加前缀(即l.fieldname,c.fieldname),以便我可以告诉您从哪个表中获取它们。无论如何,我在下面为你制作了一些示例代码,但我不确定它是100%,因为我并不总是知道桌子,这对于正确的连接很重要,所以你可能需要调整它。
  • 在右连接表上设置条件(WHERE c.CampaignID = something)时,您将其转换为INNER JOIN。如果你想避免这种情况,那么添加“...或c.CampaignID为空”。因为右边连接的想法是, IF 有一个campaignID,你希望它是'x' ,但如果没有竞选活动,那也没关系。(对吧?)

你不能对空值求和,所以我添加了coalesce来将空值更改为零。

SELECT 
   l.LandingPageId, 
   SUM(COALESCE(Hits,0)) AS Hits, 
   SUM(PixelSum) AS Conversion 
FROM 
      Report c
   RIGHT JOIN 
      LandingPages l 
   ON
      (c.LandingPageId = l.LandingPageId )
WHERE c.CampaignId = x OR c.CampaignID is null 
AND DayDate > 'y'
GROUP BY c.LandingPageId