AND और OR के बीच वरीयता क्रम की समीक्षा करें।
अंकगणित में, जोड़ की तुलना में गुणन को अधिक प्राथमिकता दी जाती है।
उदाहरण:10+10*10 =110, लेकिन (10+10)*10 =200.
यह AND और OR के समान है। AND की प्राथमिकता OR से अधिक है, इसलिए बिना कोष्ठक के:
WHERE BookingInfo.BookingDate = '05-18-2010' AND BookingInfo.ClinicID = '1'
OR BookingInfo.ClinicID = '2'
इस तरह काम करता है:
WHERE (BookingInfo.BookingDate = '05-18-2010' AND BookingInfo.ClinicID = '1')
OR BookingInfo.ClinicID = '2'
लेकिन आप चाहते हैं कि यह इस तरह काम करे:
WHERE BookingInfo.BookingDate = '05-18-2010' AND
(BookingInfo.ClinicID = '1' OR BookingInfo.ClinicID = '2')
इसलिए यह सुनिश्चित करने के लिए कोष्ठकों में रखें कि वरीयता का क्रम आपकी इच्छानुसार काम करता है।
मैंने यह भी देखा है कि आप MM-DD-YYYY प्रारूप में तिथियों का उपयोग कर रहे हैं, जो कि दिनांक शाब्दिक के लिए MySQL द्वारा मान्यता प्राप्त नहीं है। आपको YYYY-MM-DD प्रारूप का उपयोग करना चाहिए। यह एक अलग समस्या पैदा कर सकता है।
SELECT DATE('05-18-2010'); -- returns NULL
SELECT DATE('2010-05-18'); -- returns 2010-05-18
अपनी टिप्पणी दें:
हां, मुझे यकीन है कि AND की प्राथमिकता OR से अधिक है। एक बात के लिए, MySQL में सभी ऑपरेटरों की वरीयता का पदानुक्रम यहाँ प्रलेखित है:http://dev.mysql.com/doc/refman/5.1/en/operator-precedence.html
आइए आपकी मूल रूप से बताई गई समस्या का उपयोग करके एक उदाहरण देखें:
BookingDate ClinicID
2010-05-18 2
2008-05-18 2
WHERE BookingInfo.BookingDate = '2010-05-18' AND
BookingInfo.ClinicID = '1' OR BookingInfo.ClinicID = '2'
इस अभिव्यक्ति का उपयोग करते हुए, केवल पहली पंक्ति का मिलान होना चाहिए। लेकिन आपने पाया कि दोनों पंक्तियाँ मेल खाती हैं, भले ही दूसरी पंक्ति की तिथि सही न हो। क्यों? आइए प्रत्येक तुलना को TRUE या FALSE से बदलें:
TRUE AND FALSE OR TRUE
FALSE AND FALSE OR TRUE
यदि OR की प्राथमिकता अधिक होती, तो इसका मूल्यांकन इस प्रकार किया जाता:
TRUE AND (FALSE OR TRUE)
FALSE AND (FALSE OR TRUE)
चूंकि OR TRUE के साथ संयुक्त कोई भी मान TRUE देता है, इन कोष्ठकों के अंदर उप-अभिव्यक्ति कम हो जाएगी:
TRUE AND (TRUE)
FALSE AND (TRUE)
और दूसरी पंक्ति का मिलान नहीं होगा, क्योंकि FALSE और TRUE से FALSE निकलता है। लेकिन ऐसा नहीं हो सकता, क्योंकि आपने पाया कि दूसरी पंक्ति गलत तरीके से मेल खाती है।
वास्तव में, AND की OR से अधिक प्राथमिकता है, इसलिए यह वास्तव में मूल्यांकन करता है जैसे कि आपके पास AND सबएक्सप्रेशन के आसपास कोष्ठक थे:
(TRUE AND FALSE) OR TRUE
(FALSE AND FALSE) OR TRUE
जो कम कर देता है:
(FALSE) OR TRUE
(FALSE) OR TRUE
दोनों ही मामलों में, FALSE या TRUE से TRUE मिलता है, और दोनों पंक्तियाँ मेल खाती हैं।
तो कोष्ठक के बिना, डिफ़ॉल्ट शब्दार्थ यह है कि AND की OR से अधिक प्राथमिकता है। आपको कोष्ठक चाहिए:
WHERE BookingInfo.BookingDate = '2010-05-18' AND
(BookingInfo.ClinicID = '1' OR BookingInfo.ClinicID = '2')