Oracle Riddle,使用'IN'而不是'Or'

时间:2014-11-12 19:35:14

标签: sql oracle

问题很简单,我有两段代码,不明白它们是如何产生不同结果的。事实上,在某些情况下,第一段代码产生的结果是第二段代码的两倍多。请帮助我理解它们之间的区别,我认为它们会执行相同的操作。

SELECT DISTINCT COUNT(*), EYSOURCESYSTEM
FROM MERCK_SCSA_1028_THIRD_RN
WHERE TRIM(PAYMENTTERMS) = '0' OR TRIM(PAYMENTTERMS) = '0.000'
AND POSTINGDATEYEAR = '2014'
GROUP BY EYSOURCESYSTEM
ORDER BY COUNT(*) DESC

SELECT DISTINCT COUNT(*), EYSOURCESYSTEM
FROM MERCK_SCSA_1028_THIRD_RN
WHERE TRIM(PAYMENTTERMS) IN ('0', '0.000')
AND POSTINGDATEYEAR = '2014'
GROUP BY EYSOURCESYSTEM
ORDER BY COUNT(*) DESC

3 个答案:

答案 0 :(得分:6)

你的第一个就像是

  

paymentterms =='0'|| paymentterms =='0.000'&& postingdateyear ='2014'

(编辑1:请参阅Operator Precedence参考;请注意&&的优先级高于||

您的第一个陈述将按如下方式评估:

  

paymentterms =='0'|| (paymentterms =='0.000'&& postingdateyear ='2014')

相比之下,你的第二个就像是

  

(paymentterms =='0'|| paymentterms =='0.000')&& postingdateyear ='2014'

因为它们是以不同的顺序进行评估,所以第一个和第二个语句不执行相同的查询。

编辑2:添加维恩图。

由于第一个图表中无关的'0' but not '2014'绿色部分,您将获得更多行。 Venn Diagram of query 1 vs query 2

使用IN的第二个查询似乎是正确的查询。

答案 1 :(得分:1)

评论和其他答案都是正确的,但我想我会为你澄清一下:

WHERE TRIM(PAYMENTTERMS) IN ('0', '0.000') 
  AND POSTINGDATEYEAR = '2014'

仅包含2014年POSTINGDATEYEAR也有PAYMENTTERMS 0 / 0.0000的记录,

虽然:

WHERE TRIM(PAYMENTTERMS) = '0' 
   OR TRIM(PAYMENTTERMS) = '0.000'
  AND POSTINGDATEYEAR = '2014'

包括PAYMENTTERMS为0的所有记录,无论年份如何,以及PAYMENTTERMS为0.000且2014年为POSTINGDATEYEAR的记录。

答案 2 :(得分:0)

如果按照数据库的方式添加括号,则显而易见:

第一个相当于:

WHERE (TRIM(PAYMENTTERMS) = '0') 
   OR (TRIM(PAYMENTTERMS) = '0.000' AND POSTINGDATEYEAR = '2014')

而第二个相当于:

WHERE (TRIM(PAYMENTTERMS) = '0' OR TRIM(PAYMENTTERMS) = '0.000')
  AND (POSTINGDATEYEAR = '2014')