我在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,我会得到一个空的记录集,而且这不好。我必须参考两个时间表,因为每个时间表涵盖一个月,而工资时间跨越第一个月的最后一周和下一个月的第一周。
请告知。
答案 0 :(得分:1)
Access查询设计器添加了太多不需要的括号,我认为在这种情况下这些逻辑很混乱。以下是db引擎处理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
的{{1}}位于您的目标日期范围内且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)
答案 1 :(得分:0)
你的情况如下:
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和B”的任何内容,以及带有“C”的任何内容,但您需要“A和B”或“A和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;