SQL 查询结果不是我所期望的

SQL query results not what I expect

我正在 Access 2010 中测试以下 SQL 查询:

SELECT 
    Employees.Corps_ID, Employees.Last_Name, Employees.First_Name, 
    Shifts.Start_Date_Time, Shifts.End_Date_Time, 
    DateDiff('n',Shifts.Start_Date_Time,Shifts.End_Date_Time) AS SubTotalMinutes, 
    Locations.Location_Name
FROM 
    (Locations 
INNER JOIN 
    Shifts ON Locations.Location_ID = Shifts.Location) 
INNER JOIN 
    (Employees INNER JOIN Employees_Shifts ON Employees.Employee_ID = Employees_Shifts.Employee_ID) ON Shifts.Shift_ID = Employees_Shifts.Shift_ID 
WHERE 
    (((Shifts.Start_Date_Time) Between #2015/09/26# And #2015/10/09#) 
     AND ((Shifts.Schedule_ID) = 1) OR ((Shifts.Schedule_ID) = 2)) 
ORDER BY 
    Employees.Last_Name;

请注意日期范围Between #2015/09/26# And #2015/10/09#。那是 9 月 26 日。到 10 月 9 日。这表示支付期。查询运行没有错误,但是,结果显示 10 月 9 日之后的记录。事实上,它们一直持续到月底。我不明白为什么要这样做。有人有解释吗?

仅供参考,我认为这可能与条件有关:

(((Shifts.Schedule_ID) = 1) OR ((Shifts.Schedule_ID) = 2)) 但是如果我将 OR 更改为 AND,我会得到一个空记录集,这并不好。我必须参考两个时间表,因为每个时间表都涵盖一个月,并且支付期跨越第一个月的最后一周和下个月的第一周。

请指教

Access 查询设计器添加了太多不必要的括号,我认为这些会使这种情况下的逻辑变得混乱。以下是数据库引擎如何处理您的 WHERE 条件...

WHERE
       (Shifts.Start_Date_Time Between #2015/09/26# And #2015/10/09# AND Shifts.Schedule_ID=1)
    OR Shifts.Schedule_ID=2

所以基本上,如果 Start_Date_Time 在您的目标日期范围内且 Schedule_ID=1 的行将包含在查询结果集中。或者,如果它的 Schedule_ID=2 行将被包含,而不考虑它的 Start_Date_Time.

我认为你实际上想要这个...

        Shifts.Start_Date_Time Between #2015/09/26# And #2015/10/09#
    AND (Shifts.Schedule_ID=1 OR Shifts.Schedule_ID=2)

但对我来说,使用 IN 列表来表示 Schedule_ID 值会更清楚...

        Shifts.Start_Date_Time Between #2015/09/26# And #2015/10/09#
    AND Shifts.Schedule_ID IN (1,2)

你的情况是这样的:

WHERE (((Shifts.Start_Date_Time) Between #2015/09/26# And #2015/10/09#) AND ((Shifts.Schedule_ID)=1) OR ((Shifts.Schedule_ID)=2)) 

让我们让它更容易阅读:

WHERE (Shifts.Start_Date_Time Between #2015/09/26# And #2015/10/09#) AND (Shifts.Schedule_ID=1) OR (Shifts.Schedule_ID=2) 

所以就像:

WHERE A and B OR C

这将显示带有 "A and B" 的任何内容,以及带有 "C" 的任何内容,但您想要 "A and B" 或 "A and C"。

SELECT Employees.Corps_ID, Employees.Last_Name, Employees.First_Name, Shifts.Start_Date_Time, Shifts.End_Date_Time, DateDiff('n',Shifts.Start_Date_Time,Shifts.End_Date_Time) AS SubTotalMinutes, Locations.Location_Name
FROM (Locations INNER JOIN Shifts ON Locations.Location_ID = Shifts.Location) INNER JOIN (Employees INNER JOIN Employees_Shifts ON Employees.Employee_ID = Employees_Shifts.Employee_ID) ON Shifts.Shift_ID = Employees_Shifts.Shift_ID 
WHERE (((Shifts.Start_Date_Time) Between #2015/09/26# And #2015/10/09#) AND ((Shifts.Schedule_ID)=1) OR ((Shifts.Schedule_ID)=2))) 
ORDER BY Employees.Last_Name;