为什么以下查询会返回不同的结果集?
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的简写语法。我一直在看这个问题,也许我错过了一些小事?
...谢谢
答案 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语法更明确。