我有一个存储过程,用于检查在我的数据库中预订的假期,并且它不应该考虑状态为“已拒绝”或“已取消”的假期,但o我的数据库中只有一条记录具有被拒绝的状态但是这个select语句返回1?
SELECT COUNT(*) JobRoleID
FROM Employees
RIGHT JOIN Holidays
ON Employees.ID = Holidays.EmployeeID
WHERE Holidays.Status <> 'Declined' AND Holidays.Status <> 'Cancelled'
AND (Holidays.Startdate <= '2014/04/28' AND Holidays.Enddate >= '2014/04/30')
OR (Holidays.Startdate >= '2014/04/28' AND Holidays.Enddate <= '2014/04/30')
OR (Holidays.Startdate <= '2014/04/30' AND Holidays.Enddate >= '2014/04/30')
OR (Holidays.Startdate <= '2014/04/28' AND Holidays.Enddate >= '2014/04/28')
OR (Holidays.StartDate = '2014/04/28' AND Holidays.EndDate = '2014/04/30')
答案 0 :(得分:2)
此处需要考虑运营商优先级。
Not --> AND --> OR
不优先于AND,AND优先于OR。使用这些嵌套的AND和OR,最好将它们放在paranthesis中。
WHERE Holidays.[Status] <> 'Declined' AND Holidays.[Status] <> 'Cancelled'
AND
( (Holidays.Startdate <= '2014/04/28' AND Holidays.Enddate >= '2014/04/30')
OR (Holidays.Startdate >= '2014/04/28' AND Holidays.Enddate <= '2014/04/30')
OR (Holidays.Startdate <= '2014/04/30' AND Holidays.Enddate >= '2014/04/30')
OR (Holidays.Startdate <= '2014/04/28' AND Holidays.Enddate >= '2014/04/28')
OR (Holidays.StartDate = '2014/04/28' AND Holidays.EndDate = '2014/04/30')
)
同样避免使用Sql server关键字作为列名,如果你在sql中使用它们时有一些方括号[]
。
答案 1 :(得分:2)
WHERE A AND B AND C OR D AND E OR F AND G
被视为与
相同WHERE (A AND B AND C) OR (D AND E) OR (F AND G)
因此,如果除了第一个之外的任何日期比较实际上都是真的,那么整个WHERE
子句都会得到满足。
而且,顺便说一句,看起来你正试图找出两个日期范围是否重叠,并且在一个非常复杂的问题上进行。你应该只需要进行两次比较。如果出现以下两个日期范围重叠:
所以,比如:
SELECT COUNT(*) JobRoleID
FROM Employees
RIGHT JOIN Holidays
ON Employees.ID = Holidays.EmployeeID
WHERE Holidays.Status <> 'Declined' AND Holidays.Status <> 'Cancelled'
AND Holidays.StartDate <= '20140430' AND '20140428' <= Holidays.EndDate
应该相当于您的多重比较。