为什么不同的SQL结果?

时间:2009-05-15 19:41:31

标签: sql sql-server-2008 join

为什么以下查询会返回不同的结果集?

select count(ml.link_type),mc.conv_string
from MSP_CONVERSIONS mc,MSP_LINKS ml
where ml.PROJ_ID = 4
and mc.STRING_TYPE_ID = 3
and mc.CONV_VALUE *= ml.link_type
group by mc.conv_string

select count(ml.link_type),mc.conv_string
from MSP_CONVERSIONS mc left outer join MSP_LINKS ml on mc.CONV_VALUE = ml.LINK_TYPE
where ml.PROJ_ID = 4
and mc.STRING_TYPE_ID = 3
group by mc.conv_string

第一个查询返回:

  

3 FF

     

10790 FS

     

0 SF

     

117 SS

第二个查询返回:

  

3 FF

     

10790 FS

     

117 SS

两个查询都针对SQL Server 2008 Standard数据库运行。我无法理解为什么返回两个不同的结果集?我认为* =是LEFT OUTER JOIN的简写语法。我一直在看这个问题,也许我错过了一些小事?

...谢谢

2 个答案:

答案 0 :(得分:4)

因为您的第一个查询实际上与此相同:

select count(ml.link_type),mc.conv_string
from MSP_CONVERSIONS mc
LEFT JOIN MSP_LINKS ml
    ON ml.PROJ_ID = 4
    and mc.STRING_TYPE_ID = 3
    and mc.CONV_VALUE = ml.link_type
group by mc.conv_string

您已将所有条件提升到联接中,从而无法完全过滤掉MSP_CONVERSIONS表中的任何行。最好始终坚持使用完整的“LEFT / INNER JOIN”语法,避免混淆。

答案 1 :(得分:2)

“* =”并不像旧式的ANSI OUTER JOIN语法那样“简写”语法。不要使用它。另外,一般情况下,如果你的选择中有“左外连接b ...”,那么在WHERE子句中在“b”上添加附加标准是一个坏主意 - 如果它被读作过滤应用于结果对于连接,它将丢弃b中没有匹配的所有行 - 有效地将外连接转换为内连接。

这与Joel所写的内容有关 - 在“ON”子句中具有所有条件意味着在加入时应用过滤,这是不同的结果。 ANSI语法更明确。