2015-08-14 60 views
0

以下查询生成不同的计数。在我看来,它们是相同的。使用COALESCE和OR的SQL Server结果有所不同

SELECT 
    COUNT(*) 
FROM 
    item1 
RIGHT JOIN 
    (Item2 
INNER JOIN 
    item_master ON Item2.Number = item_master.number) AND (item1.itemId = Item2.itemId) 
WHERE 
    COALESCE([Item2].[Amount], item1.Amount, [item_master].[amount], 0) > 0 

SELECT 
    COUNT(*) 
FROM 
    item1 
RIGHT JOIN 
    (Item2 
INNER JOIN 
    item_master ON Item2.Number = item_master.number) AND (item1.itemId = Item2.itemId) 
WHERE 
    (Item2.Amount is not NULL and Item2.Amount > 0) OR 
    (item1.Amount is not NULL and item1.Amount > 0) OR 
    (item_master.amount is not NULL and item_master.amount > 0) 
+0

额外的','在COALESCE' 0'参数是不必要的和-IN我意见混淆。 – GolezTrol

+0

但是不是NULL> 0的问题? – phpdev76

+0

这会导致错误,就像'0> 0'一样。 :)你也不需要在第二个查询中使用'Item2.Amount不是NULL'和类似的检查。 – GolezTrol

回答

5

它们不同。 COALESCE([Item2].[Amount], item1.Amount, [item_master].[amount], 0) > 0为真,如果三者的第一个非空值,如果有任何非空值大于0

+0

,但评估时不一样吗? – phpdev76

+0

否。如果Item2.Amount为0且item1.Amount为1,则无论Item1.Amount中的“1”如何,COALESCE仍将返回0并且整个表达式(0> 0)将为false。在普通英语中,“First non-null”和“Any”之间的区别有很大不同。 – GolezTrol

+0

谢谢!不知道为什么它没有点击之前 – phpdev76

0

这里更大大于0

第二个条件是真就是为什么他们是不同的:合并只会对第一个非空值进行评估。第二个查询将接受3个输入中的任何一个进行评估。

取例如值[-1,5,空]

  • 所述第一查询:评估为假,因为-1 < = 0
  • 所述第二查询:5> 0,所以它评估为真。

,如果你想在第一个查询中使用聚结,你会想要做这样的事情:

where (coalesce(item2.amount, 0) > 0 
or coalesce(item1.amount, 0) > 0 
or coalesce(item_master.amount, 0) > 0)