Декартово соединение с несравненными рядами - PullRequest
1 голос
/ 22 апреля 2019

Я не могу заставить мой запрос работать, когда соединение LEFT не совпадает. Я думаю, что это связано с декартовым соединением. Вот запрос, который работает:

select i.id, z.WeekNum, 0, count(s.id) from my156rowtable as i
left JOIN (select YEARWEEK( @startDate ) WeekNum, @startDate := date_add( @startDate, interval 1 week ) EndOfWeek
from 
(select @startDate := '2016-04-20') sqlv,
my156rowtable
limit 156 ) z
on 1=1
where i.id = 2 and s.id = 0
group by z.WeekNum, s.id

Что возвращает:

|             2 |  201836 | 0 |        1 |
|             2 |  201837 | 0 |        1 |
|             2 |  201838 | 0 |        1 |
|             2 |  201839 | 0 |        1 |
|             2 |  201840 | 0 |        1 |
|             2 |  201841 | 0 |        1 |

, но с добавлением stats_to_my156rowtable я получаю строки 201838 и 201839, пропущенные.

select i.id, z.WeekNum, 0, count(s.id) from my156rowtable as i
left JOIN (select YEARWEEK( @startDate ) WeekNum, @startDate := date_add( @startDate, interval 1 week ) EndOfWeek
from 
(select @startDate := '2016-04-20') sqlv,
my156rowtable
limit 156 ) z
on 1=1
left join stats_to_my156rowtable as s
on i.id = s.sid and z.WeekNum = YearWeek(s.date)
where i.id = 2 and s.id = 0
group by z.WeekNum, s.id

возвращается:

|             2 |  201836 | 0 |                  8 |
|             2 |  201837 | 0 |                 14 |
|             2 |  201840 | 0 |                  9 |

если нет совпадений, я бы хотел, чтобы count было 0. Я подумал, что смогу сделать это с case или coalesce позже, но без возврата я не найду много удачи.

1 Ответ

2 голосов
/ 22 апреля 2019

Ваше условие в правой таблице в предложении WHERE превращает ваш LEFT JOIN в INNER JOIN. По сути, он отфильтровывает строки, которые не имеют id = 0, включая ваши NULL строки. Возможно, перемещение условия в предложение ON решит вашу проблему.

select i.id, z.WeekNum, 0, count(s.id) 
from my156rowtable as i
left JOIN (
    select YEARWEEK( @startDate ) WeekNum, @startDate := date_add( @startDate, interval 1 week ) EndOfWeek
    from (
        select @startDate := '2016-04-20'
    ) sqlv, my156rowtable
    limit 156 
) z on 1=1
left join stats_to_my156rowtable as s on i.id = s.sid and z.WeekNum = YearWeek(s.date) AND s.id = 0
where i.id = 2
group by z.WeekNum, s.id
...