所以我是一个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
这会给约翰逊带来结果,但其他人也是如此。另:
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
这会返回我指定日期的结果,但也会返回其他结果。我的语法错了吗?我不知道我在做什么吗?请帮助初学者。谢谢!
答案 0 :(得分: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'
的工作原理如下:
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 OR TRUE都为TRUE,两行都匹配。
因此,如果没有括号,默认语义是AND的优先级高于OR。你需要括号:
WHERE BookingInfo.BookingDate = '2010-05-18' AND
(BookingInfo.ClinicID = '1' OR BookingInfo.ClinicID = '2')
答案 1 :(得分:1)
这可能是因为你的OR条件没有括号。请尝试以下更新版本:
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 IN ('1', '2')
ORDER BY BookingInfo.BookingDate DESC
此外,为SQL添加一些格式将使其更具可读性。这将帮助您获得SO的答案,并帮助最终查看您的代码的任何其他人。
答案 2 :(得分:0)
应该归功于@Randolph Potter:
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
答案 3 :(得分:0)
您需要在WHERE
之前的OR
子句的部分周围添加括号。在第一个示例中,您的意思是
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
但由于AND
的优先级高于OR
,因此实际正在做的是
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
因此,您将看到 ClinicID
等于2的每个行;不只是约翰逊的。
答案 4 :(得分:0)
如果你在2个ClinicID条件周围放置括号,它应该可以工作。
见下文:
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
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