我基本上是在尝试修改this存储过程。
修改后的存储过程:
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
?
答案 0 :(得分:4)
首先,不是您的示例代码
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子句条件直到处理外连接之后才会应用(外部的行被添加回来)所以你需要将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;
答案 1 :(得分:3)
如果将所有条件都置于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;
答案 2 :(得分:2)
将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;
通过在WHERE子句中放入ClientId比较,您实际上将LEFT JOIN
转回INNER JOIN
上的ClientId
。
答案 3 :(得分:0)
问题是=运算符在SQL中不是NULL安全的。 NULL = NULL
是假的。你必须使用NULL安全的等价物,如果我在MySQL上正确记得是<=>
。您也可以使用COALESCE
功能或将a=b
写为(a=b OR a IS NULL or b IS NULL)
。