Предложение WHERE, приводящее к тому, что таблица пропускает правило LEFT JOIN
Я по сути пытаюсь изменить эту хранимую процедуру.
Модифицированная хранимая процедура:
CREATE PROCEDURE sp1(d1 date, d2 date, client INT(10))
declare d datetime;
create TEMPORARY TABLE foo (d date NOT NULL, Amount INT(10) DEFAULT 0);
set d = d1;
while d <= d2 do
insert into foo (d) values (d);
set d = date_add(d, interval 1 day);
end while;
SELECT SUM(p.Amount), foo.d
FROM foo LEFT JOIN ItemTracker_dbo.Payment ON foo.d = p.Datetime
WHERE p.ClientId = ClientId
GROUP BY
foo.d;
DROP TEMPORARY TABLE foo;
end PROCEDURE
ПРИМЕЧАНИЕ: предложение WHERE... p.ClientId = client
Я ломал свой мозг, пытаясь понять, почему он опускает нули.
после удаленияWHERE p.ClientId = client
процедура стала возвращать NULL...
Почему в предложении WHERE пропущены пустые строки? Я, вероятно, неправильно понимаю, что именно LEFT JOIN
является.
Как я могу пойти о фильтрации SUM(p.Amount)
результаты только вернуть сумму WHERE clientId = client
?
4 ответа
Это должно работать, если вы поставите все условия в LEFT JOIN
состояние:
SELECT SUM(p.Amount), foo.d
FROM foo
LEFT JOIN ItemTracker_dbo.Payment p ON foo.d = p.Datetime AND p.ClientId = ClientId
GROUP BY
foo.d;
Прежде всего, это не ваш пример кода
SELECT SUM(p.Amount), foo.d
FROM foo LEFT JOIN ItemTracker_dbo.Payment ON foo.d = p.Datetime
WHERE p.ClientId = ClientId
GROUP BY
foo.d;
не хватает p
для псевдонима для таблицы ItemTracker_dbo.Payment
?? т. е. не должен читать:
SELECT SUM(p.Amount), foo.d
FROM foo
LEFT JOIN ItemTracker_dbo.Payment p
ON foo.d = p.Datetime
WHERE p.ClientId = ClientId
GROUP BY foo.d;
В любом случае, причина возникновения этой проблемы заключается в том, что условия условия не применяются до тех пор, пока не будет обработано внешнее соединение (где строки с внешней стороны добавлены обратно). Поэтому необходимо переместить условие where в условие соединения:
SELECT SUM(p.Amount), foo.d
FROM foo
LEFT JOIN ItemTracker_dbo.Payment p
ON foo.d = p.Datetime
And p.ClientId = ClientId
GROUP BY foo.d;
Переместить WHERE
пункт в ON
пункт, как это:
SELECT SUM(p.Amount), foo.d
FROM foo LEFT JOIN ItemTracker_dbo.Payment ON foo.d = p.Datetime
and p.ClientId = ClientId
GROUP BY
foo.d;
Поместив сравнение ClientId в предложение WHERE, вы эффективно перевернули LEFT JOIN
обратно в INNER JOIN
на ClientId
,
Проблема в том, что оператор = не является NULL-безопасным в SQL. NULL = NULL
ложно Вы должны использовать NULL-безопасный эквивалент, который, если я правильно помню, <=>
на MySQL. Вы также можете использовать COALESCE
функция или запись a=b
как (a=b OR a IS NULL or b IS NULL)
,