MS Access - Использование значений времени без значений даты - PullRequest
1 голос
/ 18 октября 2011

Используя построитель выражений, я создал оператор 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 ]

6 голосов
/ 18 октября 2011

Этот SQL должен работать, если значения вашего поля [Time] включают 0 как целое число (число дня).Дважды проверьте, содержат ли ваши значения [Time] ненулевой компонент дня.

SELECT Format([Time], "yyyy-mm-dd hh:nn:ss") AS formatted_date_time
FROM YourTable;

Если в этом запросе отображаются значения [Time], которые включают дату, отличную от 30.12.1899, вы можете использоватьфункция TimeValue () для извлечения временных частей из этих значений.(Подробности см. В разделе справки Access.) Функция фактически даст вам то же время суток 30.12.1899, то есть нулевой день.Как упоминалось в HK1, не существует такого понятия, как тип данных времени (для VBA или механизма обработки данных);есть только дата / время, и всегда включает значение дня, представленное как общее количество дней с нулевого дня (30.12.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 голос
/ 18 октября 2011

Вот несколько дополнительных предложений ...

Если ваши значения [Time] могут содержать компонент целого числа (дня), отличный от нуля, вы можете попробовать следующий вариант предложения @ 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

В качестве альтернативы, если вы хотите применить предположение, что значения [Time] не не содержат компонент целого числа, вы можете установить свойство «Правило проверки» поля в базовой таблице ( если есть) до:

>=0 And <1
...