MySQL 8.0 возвращает 0 строк с LEFT JOIN, чтобы вернуть 1 строку со значением 0 столбца - PullRequest
0 голосов
/ 16 декабря 2018

Вот SQL-запрос:

select user.*, count(call_out_end.id) as calls
from user
left join call_out_end on call_out_end.employer_id = user.id
where user.id = 949 and call_out_end.callstart >= '2018-12-09 00:00:00'
group by user.id

И этот запрос возвращает ровно 0 строк (должен возвращать 1 строку с вызовами столбцов = 0).

enter image description here

Если я изменю SQL-запрос на:

select user.*, count(call_out_end.id) as calls
from user
left join call_out_end on call_out_end.employer_id = user.id
where user.id = 949
group by user.id

MySQLWorkbench возвращает 1 строку:

enter image description here

... но это не то, что я хочу:)

Хочу отметить, что нет записей , которые удовлетворяют условию: call_out_end.callstart >= '....', поэтому я ожидаю получить0 звонков.

Где я что-то не так делаю?

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Вы используете LEFT JOIN для опционально таблица соответствия вторичной таблицы call_out_end.Если совпадений нет, вы все равно хотите отобразить записи из первичной таблицы user.

Проблема с вашим запросом состоит в том, что ваше предложение WHERE ссылается на поле из вторичной таблицы (callstart),Следовательно, когда LEFT JOIN не совпадает, callstart в предложении WHERE появляется NULL, в результате чего соответствующая запись отфильтровывается.

Для решения проблемы необходимо переместитьфильтр в этом поле от предложения WHERE до ON части LEFT JOIN.

select user.*, count(call_out_end.id) as calls
from user
left join call_out_end
    on call_out_end.employer_id = user.id
    and call_out_end.callstart >= '2018-12-09 00:00:00'
where user.id = 949
group by user.id

Концептуально это тот же запрос, что и гораздо более уродливый:

select user.*, count(call_out_end.id) as calls
from user
left join call_out_end
    on call_out_end.employer_id = user.id     
where 
    user.id = 949
    and (
        call_out_end.employer_id IS NULL
        or call_out_end.callstart >= '2018-12-09 00:00:00'
    )
group by user.id
0 голосов
/ 16 декабря 2018

Фильтры на второй таблице в left join должны быть указаны в предложении on:

select u.*, count(coe.id) as calls
from user u left join
     call_out_end coe
     on coe.employer_id = user.id and
        coe.callstart >= '2018-12-09'
where u.id = 949 
group by u.id;

Если условие указано в предложении WHERE, то внешнее объединение превращается ввнутреннее соединение.Зачем?Несовпадающие значения callstart имеют значение NULL и не могут сравниваться.

Обратите внимание, что я также добавил псевдонимы таблиц в запрос.Это облегчает написание и чтение.Я также удалил компонент времени из константы даты.Это не нужно.

С group by u.id все в порядке, при условии, что u.id является первичным ключом в users (что, без сомнения, является).

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