左连接逻辑不像预期的那样

时间:2014-09-24 16:06:42

标签: mysql sql

我创建了一个查询,我相信该查询应该返回表1中的所有电子邮件地址。

如果我去SELECT COUNT(email), COUNT(DISTINCT email) contacts.sid208我得到200,000和175000。

考虑到这一点,通过使用左连接,来自以下查询结果的电子邮件数量应该相同吗?

SELECT 
    COUNT(email), COUNT(DISTINCT email)
FROM
    (SELECT 
        co.email,
            env.env_medium,
            CAST(MIN(co.created) AS DATE) AS first_contact,
            MIN(CASE
                WHEN my.my_id = 581 THEN my.data
            END) AS Created,
            MIN(CASE
                WHEN my.my_id = 3347 THEN my.data
            END) AS Upgraded
    FROM
        contacts.sid208 co
    LEFT JOIN contacts.my208 my ON co.id = my.eid
    LEFT JOIN contacts.env208 env ON env.eid = co.id
    WHERE
        my_id = 581 OR my_id = 3347
    GROUP BY email) b1

但是,如果我按比例保持比例,那么这里的结果是150000和150000。

我预计结果为175000。

我对LEFT JOIN的理解是,来自contacts.sid208的所有记录都将被维护,无论它们是否出现在my208或env208中。

我的理解是否存在缺陷?希望我的查询对民间有意义,如果有更多信息我可以添加以使我的问题更清楚,让我知道。

1 个答案:

答案 0 :(得分:2)

对于左连接,也将条件移动到连接:

SELECT 
    COUNT(email), COUNT(DISTINCT email)
FROM
    (SELECT 
        co.email,
            env.env_medium,
            CAST(MIN(co.created) AS DATE) AS first_contact,
            MIN(CASE
                WHEN my.my_id = 581 THEN my.data
            END) AS Created,
            MIN(CASE
                WHEN my.my_id = 3347 THEN my.data
            END) AS Upgraded
    FROM
        contacts.sid208 co
    LEFT JOIN contacts.my208 my 
        ON co.id = my.eid
        AND (my_id = 581 OR my_id = 3347)
    LEFT JOIN contacts.env208 env ON env.eid = co.id
    GROUP BY email) b1

如果您不这样做,您将首先执行连接,从而产生sid208中的所有行,无论如何,null值都会丢失电子邮件。但是随后where子句中的过滤开始了,无论如何都会删除那些记录。

当您将所有这些条件移动到联接时,您将获得所有行,并且只有当电子邮件具有匹配的联系人ID时才会加入,并且他们自己的ID为581或2247.