不明白为什么这两个查询给出不同的结果

时间:2010-02-09 13:36:27

标签: sql-server aggregation

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

没有必要在属性表上表示给定的个体,因为它们可能永远不会添加属性,并且如果它们具有多个属性,它们可以出现多次。

我想获得一个单独的引用列表以及它们的特定属性的计数。但需要通过电子邮件地址进行搜索,因为个人可以共享电子邮件地址(不要让我开始)......

我的第一次刺伤是

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

返回一行,其中individual_Ref和计数为0

我并不是说我的理解是错误的,因此我认为“我的困惑是什么?”是个问题。

4 个答案:

答案 0 :(得分:3)

以下部分导致联接改变:

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_code上放置where子句,您已将左连接转换为内连接,例如如果不存在属性记录,则返回null,这将使where子句失败。 (因为a.attr_code_ref不能是4119,所以没有记录。)

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

答案 1 :(得分:1)

更改第一个:

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

你会得到相同的结果

答案 2 :(得分:1)

将子查询转换为LEFT JOIN时,子查询中的相关WHERE条件将转到联接的ON子句,而不是WHERE子句:< / p>

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

答案 3 :(得分:0)

在第一个查询中,您将加入这两个表,并查找与您的条件相对应的所有行 - 没有。

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