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;
我正在 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;