【问题标题】:Avg on datetime in AccessAccess 中的日期时间平均值
【发布时间】:2008-11-20 15:57:53
【问题描述】:

我正在将一些查询从 Access 移植到 T-SQL,编写查询的人在 datetime 列上使用了 Avg 聚合函数。这在 T-SQL 中不受支持,我可以理解为什么 - 这没有意义。什么是平均化?

所以我正要开始逆向工程,当 Access 使用 Avg 聚合日期时间时,它会做什么,但我想我会先在这里提出问题。

【问题讨论】:

    标签: sql sql-server tsql ms-access


    【解决方案1】:

    我认为 Access 正在对日期的数字表示进行平均。您可以在 T-SQL 中使用以下方法进行类似操作...

    select AverageDate = cast(avg(cast(MyDateColumn as decimal(20, 10))) as datetime)
    from    MyTable
    

    【讨论】:

    • 是的,这就是我的假设,这可能是最合乎逻辑的事情。我想知道它是否可能没有像一天中的平均时间之类的那样进行某种分区。
    • Jet 日期字段是日期的整数值加上时间的十进制值。如果您只想对日期进行平均,请使用整数值。
    • MS SQL 类似 - 转换为 int 只会给你日期部分的平均值
    【解决方案2】:

    我对非 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
    

    【讨论】:

      【解决方案3】:

      @David W. Fenton:“Jet 日期字段是日期的整数值加上时间的十进制值”——不,ACE/Jet DATETIME 列是 FLOAT(同义词 @987654323 @、FLOAT8IEEEDOUBLENUMBER) 有限制,例如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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-25
        • 2017-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-30
        • 1970-01-01
        相关资源
        最近更新 更多