【发布时间】:2008-11-20 15:57:53
【问题描述】:
我正在将一些查询从 Access 移植到 T-SQL,编写查询的人在 datetime 列上使用了 Avg 聚合函数。这在 T-SQL 中不受支持,我可以理解为什么 - 这没有意义。什么是平均化?
所以我正要开始逆向工程,当 Access 使用 Avg 聚合日期时间时,它会做什么,但我想我会先在这里提出问题。
【问题讨论】:
标签: sql sql-server tsql ms-access
我正在将一些查询从 Access 移植到 T-SQL,编写查询的人在 datetime 列上使用了 Avg 聚合函数。这在 T-SQL 中不受支持,我可以理解为什么 - 这没有意义。什么是平均化?
所以我正要开始逆向工程,当 Access 使用 Avg 聚合日期时间时,它会做什么,但我想我会先在这里提出问题。
【问题讨论】:
标签: sql sql-server tsql ms-access
我认为 Access 正在对日期的数字表示进行平均。您可以在 T-SQL 中使用以下方法进行类似操作...
select AverageDate = cast(avg(cast(MyDateColumn as decimal(20, 10))) as datetime)
from MyTable
【讨论】:
我对非 MS DBMS 更熟悉,但是... 由于您无法添加两个 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() 函数中减去的日期时间加回来,你就会得到一个合理的答案。
这确实假设使用的 DBMS 支持 SQL 标准“时间戳”表示法,并适当地支持 INTERVAL 类型。两个 DATETIME 或 TIMESTAMP 值之间的差异应该是一个 INTERVAL(实际上是 INTERVAL DAY(9) TO SECOND(6),准确度适中,尽管“9”有点值得商榷)。
当对我使用的 DBMS 进行适当修改时,表达式“有效”:
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
【讨论】:
@David W. Fenton:“Jet 日期字段是日期的整数值加上时间的十进制值”——不,ACE/Jet DATETIME 列是 FLOAT(同义词 @987654323 @、FLOAT8、IEEEDOUBLE、NUMBER) 有限制,例如DATETIME 的最大值是 #9999-12-31:23:59:59# 尽管可以转换为 DATETIME 的最大值 FLOAT 会稍大一些,例如
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
【讨论】: