2012-04-23 328 views
5

我有這條線在我的SQL查詢:SQL查詢的WHERE子句

WHERE client = $id 
    AND (isinvoiced = 0) OR (isinvoiced = 1 and isrecurring = 1) 

其得到更多的結果,比我期待的。不過,如果我這樣寫:

WHERE client = $id 
    AND (isinvoiced = 0) OR (isinvoiced = 1 and isrecurring = 1 and client = $id) 

然後它得到我想要的結果,但這是寫這個最好的方法嗎?我只是不想再遇到這個代碼的更多問題。

+1

Google for [Distributivity rewrite rules](http://en.wikipedia.org/wiki/Distributivity)。 – onedaywhen 2012-04-23 15:32:37

+2

你確定你明白'a AND b OR c'和'a AND(b OR c)'的區別嗎?你的例子更清楚地寫成'(a AND b)或c',而不是你真正想要的。 – MatBailie 2012-04-23 15:38:08

回答

8

圍繞整個AND子句,您需要多一組()。這說明client = $id必須是真實的,其他條件中的任何一個也必須是我= isinvoiced = 0isinvoiced = 1 and isrecurring = 1的組合。

WHERE client = $id 
    AND ((isinvoiced = 0) OR (isinvoiced = 1 and isrecurring = 1)) 
+0

完美的邁克爾,多數民衆贊成我正在尋找,再次感謝......我會投票給你的答案,當它讓我。 – user979331 2012-04-23 15:27:34

+1

如果'isinvoiced = 1'與'isinvoiced = 0'正好相反(即'isinvoiced'不能包含其他值,也不包含'NULL'),則可以進一步簡化:WHERE client = $ id AND isinvoiced = 0或isrecurring = 1)'。 – 2012-04-24 05:06:57

1
where client = $id 
    and (
     isinvoiced = 0 
     or (
      isinvoiced = 1 
      and isrecurring = 1 
      ) 
     ) 
-1

如果where子句

remove -> WHERE client = $id 

,只是有

WHERE (isinvoiced = 0) OR (isinvoiced = 1 and isrecurring = 1 and client = $id) 

這是否讓你的結果你想刪除初始?

+0

OP要始終匹配「客戶端」。看到接受的答案。 – Ben 2012-04-23 21:35:08

2

添加括號在你AND條款:

WHERE client = $id 
    AND ((isinvoiced = 0) OR (isinvoiced = 1 and isrecurring = 1)) 
1

你想要的是這樣的:

WHERE client = $id AND ((isinvoiced = 0) OR (isinvoiced = 1 and isrecurring = 1)) 

如果你不把多餘的blaquets它將使一個OR與客戶restiction並給出更多結果。

0

關於SQL,您應該旨在編寫搜索條件conjunctive normal form(「AND條款的一個系列」)。有各種rewrite rules來協助這一點。

distributive rewrite law在這種情況下有用即

(P AND Q) OR R <=> (P OR R) AND (Q OR R)  

你的情況:

(isinvoiced = 0) OR (isinvoiced = 1 AND isrecurring = 1) 

可改寫爲:

(isinvoiced = 0 OR isinvoiced = 1) AND (isinvoiced = 0 OR isrecurring = 1) 

因此,無需笨重的整個搜索條件parens:

.... 
WHERE client = $id 
     AND (isinvoiced = 0 OR isinvoiced = 1) 
     AND (isinvoiced = 0 OR isrecurring = 1);