WHERE子句导致表省略LEFT JOIN规则

时间:2010-02-02 16:05:51

标签: mysql mysql-logic

我基本上是在尝试修改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

4 个答案:

答案 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; 

缺少pItemTracker_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)