使用表达式构建器,我构建了一个如下所示的switch语句:
Switch([Time]>=#12:00:00 AM# And [Time]<#7:00:00 AM#,"Before 7 am",
[Time]>=#7:00:00 AM# And [Time]<#10:00:00 AM#,"7 am - 9:59 am",
[Time]>=#10:00:00 AM# And [Time]<#5:00:00 PM#,"10 am - 4:59 pm",
[Time]>=#5:00:00 PM# And [Time]<=#9:00:00 PM#,"5 pm - 9 pm",
[Time]>#9:00:00 PM# And [Time]<#11:59:00 PM#,"After 9 pm")
但是,我注意到我的查询无法正常工作,所以我检查了SQL。奇怪的是,它看起来像这样:
Switch([Time]>=#12/30/1899# And [Time]<#12/30/1899 7:0:0#,"Before 7 am",
[Time]>=#12/30/1899 7:0:0# And [Time]<#12/30/1899 10:0:0#,"7 am - 9:59 am",
[Time]>=#12/30/1899 10:0:0# And [Time]<#12/30/1899 17:0:0#,"10 am - 4:59 pm",
[Time]>=#12/30/1899 17:0:0# And [Time]<=#12/30/1899 21:0:0#,"5 pm - 9 pm",
[Time]>#12/30/1899 21:0:0# And [Time]<#12/30/1899 23:59:0#,"After 9 pm")
AS Time_Range
所以,看起来Access正在将这些转换为日期/时间值,但我只需要时间。有没有办法做到这一点?
答案 0 :(得分:6)
如果您的[Time]字段值包含0作为整数(日期编号)部分,则SQL应该有效。仔细检查您的[时间]值是否包含非零日组件。
SELECT Format([Time], "yyyy-mm-dd hh:nn:ss") AS formatted_date_time
FROM YourTable;
如果该查询显示包含12/30/1899之外的日期的[时间]值,则可以使用TimeValue()函数从这些值中提取时间部分。 (有关详细信息,请参阅访问'帮助主题。)该功能实际上将在18/22/18(即零日)给您同一时间。正如HK1所提到的那样,没有时间数据类型(VBA或db引擎);只有日期/时间,并且始终包括一天的值,表示为自第0天(12/30/1899)以来的整数天。
编辑:如果你打算使用Switch()函数,你可以简化它。
Switch([Time]<#12/30/1899 7:0:0#,"Before 7 am",
[Time]<#12/30/1899 10:0:0#,"7 am - 9:59 am",
[Time]<#12/30/1899 17:0:0#,"10 am - 4:59 pm",
[Time]<=#12/30/1899 21:0:0#,"5 pm - 9 pm",
[Time]<#12/30/1899 23:59:0#,"After 9 pm")
AS Time_Range
IOW,你不需要把第二个条件写成......
[Time]>=#7:00:00 AM# And [Time]<#10:00:00 AM#
...因为如果[时间]早于上午7点,则第一个条件为True,第二个条件不会被评估。
Edit2 :您可以使用表格作为时间段,而不是使用Switch语句将它们编码到SQL中。
bracket_start bracket_end bracket_label
12:00:00 AM 6:59:59 AM Before 7 am
7:00:00 AM 9:59:59 AM 7 am - 9:59 am
10:00:00 AM 4:59:59 PM 10 am - 4:59 pm
5:00:00 PM 9:00:00 PM 5 pm - 9 pm
9:00:01 PM 11:59:59 PM After 9 pm
SELECT
y.[Time],
b.bracket_label
FROM
YourTable AS y,
time_brackets AS b
WHERE
y.[Time] >= b.bracket_start
AND y.[Time] <= b.bracket_end;
Edit3 :我希望time_brackets表方法(Edit2)优于查询中的Switch()表达式。如果您决定更改时间括号和/或括号标签,如果您有多个这样的查询,则表格方法将更容易维护。只需更改time_brackets表,而不是在每个查询中修改Switch()表达式。
如果您只针对单个查询执行此操作,那么这种考虑可能并不引人注目。但是,在这种情况下,我仍然更喜欢表方法,因为我发现编写复杂的Switch()表达式没有错误更具挑战性。如果我们考虑嵌套的IIf()表达式而不是Switch(),那么相同的参数也会适用(甚至更多!)。
最后,括号时间范围和标签构成数据。数据合法地属于表格。在任何可行的情况下,我宁愿避免将数据编码到SELECT语句中。这意味着我寻找在查询中避免使用Switch()或嵌套IIf()表达式的方法。这里的一个附带好处是查询设计器不会像你没有Switch()语句那样重写你的Switch()语句。 : - )
答案 1 :(得分:1)
以下是一些其他建议......
如果您的[时间]值可能包含除零以外的整数(日)成分,您可以尝试以下@ HansUp建议的变体:
Switch(Hour([Time])<7,"Before 7 am",
Hour([Time])<10,"7 am - 9:59 am",
Hour([Time])<17,"10 am - 4:59 pm",
Hour([Time])<=21,"5 pm - 9 pm",
Hour([Time])<=23,"After 9 pm")
AS Time_Range
或者,如果要强制假设[时间]值不包含整数组件,则可以在基础表中设置字段的“验证规则”属性(如果有的话):
>=0 And <1