Mysql право присоединиться к группе по проблеме - PullRequest
3 голосов
/ 28 июля 2010

У меня есть 2 таблицы:

  1. LandingPages - содержит целевые страницы для кампании.

  2. Отчеты - содержат обращения и конверсии на целевую страницу.

Я пытаюсь сделать запрос, который приносит сумму хитов и конверсий на целевую страницу,

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

Что я делаю до сих пор:

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 ]

3 голосов
/ 28 июля 2010

Хорошо.Когда я запускаю следующее, я получаю результат снизу.Это то, что вы хотите?

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 не должно быть никакой разницы, поскольку это все стандартный язык запросов.

2 голосов
/ 06 августа 2010

Во-первых, вы не сказали нам, в какой таблице хранятся таблицы Hits, PixelSum или DayDate. ? представляет этот факт в моем запросе. Очевидно, что ? нужно будет заменить соответствующим псевдонимом. Тем не менее, я предположил, что DayDate взято из таблицы отчета, поскольку вы позже упомянули проблему, если критерии даты не совпадают.

Короче говоря, вам нужно применить этот критерий в предложении ON левого соединения. Критерии предложения ON применяются перед тем, как присоединяется к таблице LandingPages. Таким образом, Campaigns <> X будет отфильтровываться в дополнение к DayDate значениям <= 'y' (кстати, какой тип данных <code>DayDate? DayDate > 'y' выглядит мне подозрительно), прежде чем присоединится таблица отчета к таблице 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

Для получения дополнительной информации о левых соединениях, вот визуальное представление .

1 голос
/ 29 июля 2010

Я беру идею Томаса и с небольшим улучшением его работы!

запрос:

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
1 голос
/ 28 июля 2010

У вас есть это: WHERE c.CampaignId = x это означает, что если целевая страница не получила никаких обращений и конверсий (и не отображается в таблице отчетов), целевая страница никогда не будет отображаться в результатах, хотя вы используете правильное объединение.Ваш c.CampaignId будет нулевым для этих целевых страниц, а c.CampaignId = x будет ложным.

try:

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 равно нулю.

1 голос
/ 28 июля 2010

Это б / к ПРАВИЛЬНОГО СОЕДИНЕНИЯ.Повторите это как:

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
0 голосов
/ 04 августа 2010

Некоторые проблемы, которые я вижу ...

  • Пожалуйста, во всех случаях ставьте префиксы для ваших столбцов (т. Е. L.fieldname, c.fieldname), чтобы я мог определить, из какой таблицы вы получаете их.,В любом случае, я сделал для вас пример кода ниже, но я не уверен в этом на 100%, так как я не всегда знал таблицу, которая важна для ПРАВИЛЬНОГО СОЕДИНЕНИЯ, поэтому вам, возможно, придется настроить его.
  • когда вы устанавливаете критерии (WHERE c.CampaignID = что-то) в правосторонней таблице, вы превращаете ее в ВНУТРЕННЕЕ СОЕДИНЕНИЕ.Если вы хотите избежать этого, то добавьте "... или c.CampaignID имеет значение null). Поскольку идея ПРАВОГО объединения заключается в том, что ЕСЛИ есть идентификатор кампании, вы хотите, чтобы он был 'x',но если нет кампании, это тоже нормально. (верно?)

вы не можете суммировать нули, поэтому я добавил объединение, чтобы изменить нули на ноль.

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
...