需要有关正确SQL的帮助

Bri*_*ang 3 mysql

所以我是一个noobie,首发,初学者 - 把所有上述内容扔给我.我正在尝试创建一个将在数据库中搜索并返回等等等等的查询.问题是,它不是很有效.这是一个示例查询 - 正如您所看到的,在其他事情之上,我试图返回姓氏为Johnson的人的结果

SELECT BookingInfo.ClinicID, BookingInfo.BookingDate, BookingInfo.BookingTime, 
  BookingInfo.Status, PatientBooking.FirstName, PatientBooking.LastName, 
  PatientBooking.DateOfBirth 
FROM BookingInfo LEFT JOIN PatientBooking 
  ON BookingInfo.PatientID = PatientBooking.PatientID 
WHERE PatientBooking.LastName = 'Johnson' AND BookingInfo.ClinicID = '1' 
  OR BookingInfo.ClinicID = '2' 
ORDER BY BookingInfo.BookingDate DESC 
Run Code Online (Sandbox Code Playgroud)

这将返回约翰逊的结果,但其他人也是如此.另一个:

SELECT BookingInfo.ClinicID, BookingInfo.BookingDate, BookingInfo.BookingTime, 
  BookingInfo.Status, PatientBooking.FirstName, PatientBooking.LastName, 
  PatientBooking.DateOfBirth 
FROM BookingInfo LEFT JOIN PatientBooking 
  ON BookingInfo.PatientID = PatientBooking.PatientID 
WHERE BookingInfo.BookingDate = '05-18-2010' AND BookingInfo.ClinicID = '1' 
  OR BookingInfo.ClinicID = '2' 
ORDER BY BookingInfo.BookingDate DESC 
Run Code Online (Sandbox Code Playgroud)

这将返回我指定的日期的结果,但也返回其他结果.我的语法错了吗?我不知道我在做什么吗?请帮助初学者.谢谢!

Bil*_*win 5

查看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'
Run Code Online (Sandbox Code Playgroud)

像这样工作:

WHERE (BookingInfo.BookingDate = '05-18-2010' AND BookingInfo.ClinicID = '1') 
  OR BookingInfo.ClinicID = '2'
Run Code Online (Sandbox Code Playgroud)

但是你希望它像这样工作:

WHERE BookingInfo.BookingDate = '05-18-2010' AND 
  (BookingInfo.ClinicID = '1' OR BookingInfo.ClinicID = '2')
Run Code Online (Sandbox Code Playgroud)

因此,请在括号中输入以确保优先顺序符合您的要求.


我还注意到你正在使用MM-DD-YYYY格式的日期,MySQL无法识别日期文字.您必须使用YYYY-MM-DD格式.这可能会导致另一个问题.

SELECT DATE('05-18-2010'); -- returns NULL
SELECT DATE('2010-05-18'); -- returns 2010-05-18
Run Code Online (Sandbox Code Playgroud)

你的评论:

你确定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'
Run Code Online (Sandbox Code Playgroud)

使用此表达式,只有第一行应匹配.但是你发现两行都匹配,即使第二行的日期不正确.为什么?让我们用TRUE或FALSE替换每个比较:

TRUE AND FALSE OR TRUE
FALSE AND FALSE OR TRUE
Run Code Online (Sandbox Code Playgroud)

如果OR具有更高的优先级,它将如下评估:

TRUE AND (FALSE OR TRUE)
FALSE AND (FALSE OR TRUE)
Run Code Online (Sandbox Code Playgroud)

由于与OR TRUE结合的任何值都为TRUE,因此这些括号内的子表达式将减少为:

TRUE AND (TRUE)
FALSE AND (TRUE)
Run Code Online (Sandbox Code Playgroud)

并且第二行不匹配,因为FALSE和TRUE产生FALSE.但那不可能,因为你发现第二行错误匹配.

实际上,AND的优先级高于OR,因此它的确如下围绕AND子表达式括号一样:

(TRUE AND FALSE) OR TRUE
(FALSE AND FALSE) OR TRUE
Run Code Online (Sandbox Code Playgroud)

减少到:

(FALSE) OR TRUE
(FALSE) OR TRUE
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,FALSE OR TRUE都为TRUE,两行都匹配.

所以没有括号,默认语义是AND的优先级高于OR.你需要括号:

WHERE BookingInfo.BookingDate = '2010-05-18' AND 
  (BookingInfo.ClinicID = '1' OR BookingInfo.ClinicID = '2')
Run Code Online (Sandbox Code Playgroud)