Среднее по дате / времени в Access - PullRequest
2 голосов
/ 20 ноября 2008

Я портирую некоторые запросы из Access на T-SQL, и те, кто написал запросы, использовали статистическую функцию Avg для столбцов datetime. Это не поддерживается в T-SQL, и я могу понять, почему - это не имеет смысла. Что усредняется?

Итак, я собирался начать реверс-инжиниринг того, что делает Access, когда он агрегирует дату и время, используя Avg, но подумал, что сначала я выброшу вопрос здесь.

Ответы [ 3 ]

3 голосов
/ 20 ноября 2008

Я полагаю, что Access усредняет числовое представление дат. Вы можете сделать подобное в T-SQL с помощью следующего ...

select AverageDate = cast(avg(cast(MyDateColumn as decimal(20, 10))) as datetime)
from    MyTable
1 голос
/ 11 июня 2009

@ Дэвид В. Фентон: «Поле даты Jet является целочисленным значением для дня плюс десятичное значение для времени» - нет, столбец ACE / Jet DATETIME равен FLOAT (синонимы DOUBLE, FLOAT8, IEEEDOUBLE, NUMBER) с ограничениями, например максимальное значение DATETIME составляет # 9999-12-31: 23: 59: 59 #, хотя максимальное значение FLOAT, которое может быть приведено к DATETIME, будет немного больше, например.

SELECT CDBL(CDATE('9999-12-31 23:59:59'))

возвращает 2958465,99998843, однако

SELECT CDATE(CDBL(2958465.9999999997))

не ошибка, тогда как

SELECT CDATE(CDBL(2958465.9999999998))

делает ошибку.

Поэтому, чтобы сохранить функциональность в SQL Server, я предлагаю преобразовать столбец DATETIME в FLOAT, например.

SELECT CAST(AVG(CAST(MyDateTimeColumn AS FLOAT)) AS DATETIME)
  from MyTable
1 голос
/ 20 ноября 2008

Я более знаком с СУБД не-MS, но ... Поскольку вы не можете добавить два значения DATETIME, вы не можете их усреднить. Тем не менее, вы можете сделать что-то похожее на:

SELECT AVG(datetime_column - TIMESTAMP '2000-01-01 00:00:00.000000') +
              TIMESTAMP '2000-01-01 00:00:00.000000'
    FROM table_containing_datetime_column;

Это вычисляет средний интервал между началом 2000 года и фактическими значениями даты и времени, а затем добавляет этот интервал к началу 2000 года. Выбор «начала 2000 года» является произвольным; до тех пор, пока дата и время, вычтенные из функции AVG (), добавлены обратно, вы получите разумный ответ.

Предполагается, что используемая СУБД поддерживает стандартную нотацию «timestamp» в SQL и, соответственно, поддерживает типы INTERVAL. Разница между двумя значениями DATETIME или TIMESTAMP должна быть ИНТЕРВАЛОМ (действительно, INTERVAL DAY (9) TO SECOND (6), чтобы быть умеренно точным, хотя '9' является спорным).

При соответствующей корректировке для СУБД, с которой я работаю, выражение «работает»:

CREATE TEMP TABLE table_containing_datetime_column
(
    datetime_column DATETIME YEAR TO FRACTION(5) NOT NULL
);

INSERT INTO table_containing_datetime_column VALUES('2008-11-19 12:12:12.00000');
INSERT INTO table_containing_datetime_column VALUES('2008-11-19 22:22:22.00000');

SELECT AVG(datetime_column - DATETIME(2000-01-01 00:00:00.00000) YEAR TO FRACTION(5)) +
    DATETIME(2000-01-01 00:00:00.00000) YEAR TO FRACTION(5)
FROM table_containing_datetime_column;

Ответ:

2008-11-19 17:17:17.00000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...