2012-04-23 51 views
5

Tôi có dòng này trong truy vấn sql của tôi:truy vấn SQL mệnh đề where

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

mà nhận được kết quả hơn tôi mong đợi. Tuy nhiên, nếu tôi viết nó như thế này:

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

sau đó nó cho tôi kết quả tôi muốn, nhưng đây là cách tốt nhất để viết? Tôi chỉ không muốn chạy vào bất kỳ vấn đề nhiều hơn với mã này.

+1

Google cho [Quy tắc ghi lại phân phối] (http://en.wikipedia.org/wiki/Distributivity). – onedaywhen

+2

Bạn có chắc bạn hiểu sự khác biệt giữa 'a AND b OR c' và' a AND (b OR c) '? Ví dụ của bạn được viết rõ ràng hơn là '(a AND b) HOẶC c', không phải những gì bạn thực sự muốn. – MatBailie

Trả lời

8

Bạn cần thêm một bộ () quanh toàn bộ mệnh đề AND. Điều này nêu rõ rằng client = $id PHẢI đúng, và một trong các điều kiện khác cũng phải đúng với tôi = isinvoiced = 0 HOẶC kết hợp của isinvoiced = 1 and isrecurring = 1.

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

Hoàn hảo Michael, đó chính xác là những gì tôi đang tìm kiếm, cảm ơn một lần nữa ... Tôi sẽ bỏ phiếu cho câu trả lời của bạn khi nó cho phép tôi. – user979331

+1

Nếu 'isinvoiced = 1' là trường hợp ngược lại của' isinvoiced = 0' (tức là 'isinvoiced' không thể giữ giá trị khác, cũng không phải' NULL'), bạn có thể đơn giản hóa nó hơn nữa: 'WHERE client = $ id AND (isinvoiced = 0 OR isrecurring = 1) '. –

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

Nếu bạn loại bỏ ban đầu mệnh đề where

remove -> WHERE client = $id 

và chỉ có

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

Liệu rằng giúp bạn có được kết quả mong muốn?

+0

OP muốn khớp với 'khách hàng' mọi lúc. Xem câu trả lời được chấp nhận. – Ben

2

Thêm ngoặc xung quanh khoản AND của bạn:

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

Nếu bạn không đặt blaquets thêm nó sẽ làm cho một OR với restiction khách hàng:

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

gì bạn muốn điều này là và cho nhiều kết quả hơn.

0

Liên quan đến SQL, bạn nên nhằm mục đích viết điều kiện tìm kiếm trong conjunctive normal form ("một điều kiện tiên quyết của AND điều khoản"). Có nhiều loại rewrite rules để hỗ trợ việc này.

Các distributive rewrite law rất hữu ích trong trường hợp này tức là

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

Trong trường hợp của bạn:

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

có thể được viết lại như sau:

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

Do đó, điều kiện tìm kiếm toàn bộ mà không trở nên cồng kềnh parens:

.... 
WHERE client = $id 
     AND (isinvoiced = 0 OR isinvoiced = 1) 
     AND (isinvoiced = 0 OR isrecurring = 1); 
Các vấn đề liên quan