两张桌子:
a)svn3
列name revno compname
b)archdetails
列name version compname inFlat
这两个查询不应该输出相同的结果。查询2的输出是正确的。 query1有什么问题?
QUERY1:
select sum(CASE WHEN inFlat=1 THEN 1 ELSE 0 END) from archdetails inner join svn3 on archdetails.compname=svn3.compname where archdetails.name='ant' AND version='1.4' AND (revno='r274642' OR revno='r274578' OR revno='r274533')
QUERY2:
select sum(CASE WHEN inFlat=1 THEN 1 ELSE 0 END) from archdetails where name='ant' AND version='1.4' AND compname IN (select compname from svn3 where revno ='r274642' OR revno='r274578' OR revno='r274533')
答案 0 :(得分:2)
如果svn3
的多个行具有相同的compname
并且还有一个请求的revno
值,则查询1将对每个svn3
行计算一次。查询2仅计算每个compname
一次。 IN
子句消除了第二个查询中的任何重复compname
条目。
如果您不想计算重复的compname
条目,则需要将它们分组到子查询中。一种方法是使用IN
子句,就像在查询2中一样。另一种选择是在子查询上使用GROUP BY
,并命名该子查询。然后将命名子查询加入archdetails
表。
如果您正在尝试解决性能问题,那么我建议将主键和外键添加到表中。我认为这会加快速度。
我看到一些评论EXISTS
有时比IN
更快,但我没有看到任何证据支持这一点。您可能想要尝试一下。
答案 1 :(得分:2)
不,两个查询不一样 - 第一个查询加入compname上的svn3记录,版本'1.4'和3个revno值之一。如果给定的compname存在多个svn3记录(版本为'1.4'且任何3 revno值),则query1将返回更多结果。
可能的解决方案:改变
sum(CASE WHEN inFlat=1 THEN 1 ELSE 0 END)
到
count(distinct CASE WHEN inFlat=1 THEN archdetails.compname END)
(假设archdetails.compname
唯一标识要在此查询中计算的每个archdetails记录,并给出其中的其他约束。)
答案 2 :(得分:0)
看过其他答案之后,我现在认为这是一个不太可能的解释,但如果不是......会保留它......
我的猜测是,这是由某处的NULL值引起的(将其归咎于NULL是一种通常有效的策略)。是archdetails.compname
还是svn3.compname
可以为空,如果是,那么这些表中是否包含空值?如果确实存在空值,则需要确定在比较空值时确切想要发生的事情。
如果它是由空值引起的,那么您的ANSI_NULLS设置也可能在此处发挥作用。