MS Access - 使用没有日期值的时间值

时间:2011-10-18 16:10:34

标签: ms-access ms-access-2007

使用表达式构建器,我构建了一个如下所示的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正在将这些转换为日期/时间值,但我只需要时间。有没有办法做到这一点?

2 个答案:

答案 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