代码之家  ›  专栏  ›  技术社区  ›  Paul D'Ambra

不明白这两个查询为什么会产生不同的结果

  •  2
  • Paul D'Ambra  · 技术社区  · 14 年前

    我有三个表(为了讨论)个人,电子邮件和属性。个人\引用将个人链接到电子邮件和属性的外键。

    不需要在属性表中表示给定的个人,因为他们可能从未添加过属性,并且如果他们有多个属性,则可以出现多次。

    我想得到一个单独引用的列表和它们的一个特定属性的计数。但需要按电子邮件地址搜索,因为它允许个人共享电子邮件地址(不要让我开始)。

    我的第一刀是

    select e.individual_ref, count(a.attr_Code_ref)
    from email e left join attribute a on e.individual_Ref = a.individual_ref
    where e.email_Address = 'example.email@adomain.net'
    and a.attr_code_Ref = 4119 
    group by e.individual_ref
    

    使用左联接确保我从电子邮件中获取单个引用(如果存在),并确保如果电子邮件中存在单个引用但属性中不存在,则获得结果。所以我想,因为这不会返回行,但是…

    select e.individual_ref, 
    (select count(a.attr_Code_ref) from attribute a where a.attr_code_Ref = 4119 and a.individual_ref = e.individual_ref)
    from email e
    where e.email_Address = 'example.email@adomain.net'
    group by e.individual_REf
    

    返回一行,其中单个引用和计数为0

    我不是说SQL被破坏了,我的理解是…所以我猜“我的困惑是什么?”是个问题。

    4 回复  |  直到 14 年前
        1
  •  1
  •   Quassnoi    14 年前

    将子查询转换为 LEFT JOIN ,相关的 WHERE 子查询中的条件转到 ON 加入条款,而不是 在哪里? 条款:

    SELECT  e.individual_ref, count(a.attr_Code_ref)
    FROM    email e
    LEFT JOIN
            attribute a
    ON      a.individual_ref = e.individual_Ref
            AND a.attr_code_Ref = 4119 
    WHERE   e.email_Address = 'example.email@adomain.net'
    GROUP BY
            e.individual_ref
    
        2
  •  3
  •   Andrew    14 年前

    以下部分导致连接发生更改:

    from email e left join attribute a on e.individual_Ref = a.individual_ref 
    where e.email_Address = 'example.email@adomain.net' 
    and a.attr_code_Ref = 4119  
    

    通过在a.attr_代码上放置WHERE子句,可以将左联接转换为内部联接,例如在不存在属性记录的情况下,它将返回空值,而这将使WHERE子句失败。(由于a.attr_code_ref不能是4119,所以没有记录。)

    你需要允许 a.attr_code_ref = 4199 or a.attr_code_ref is null

        3
  •  1
  •   Hans van Dodewaard    14 年前

    将第一个更改为:

    select e.individual_ref, count(a.attr_Code_ref)
    from email e left join attribute a on e.individual_Ref = a.individual_ref
    where e.email_Address = 'example.email@adomain.net'
    and (a.attr_code_Ref = 4119 or a.individual_ref is null)
    group by e.individual_ref
    

    你得到同样的结果

        4
  •  0
  •   Oded    14 年前

    在第一个查询中,您将联接两个表,并查找与这两个条件对应的任何行—没有。

    在第二个查询中,您将从第一个表中获取与电子邮件条件相对应的行(有一个),从另一个表中获取与第二个条件相对应的行数,其中有0行。