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

时间:2015-11-21 17:21:29

标签: sql ms-access ms-access-2010

我在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,我会得到一个空的记录集,而且这不好。我必须参考两个时间表,因为每个时间表涵盖一个月,而工资时间跨越第一个月的最后一周和下一个月的第一周。

请告知。

2 个答案:

答案 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=2Start_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;