【问题标题】:Calculate average time difference between two datetime fields per day计算每天两个日期时间字段之间的平均时间差
【发布时间】:2014-09-24 06:56:48
【问题描述】:

我有一个出租车数据库,其中包含两个日期时间字段“BookedDateTime”和“PickupDateTime”。客户需要知道从预订出租车到司机实际“接”客户的平均等待时间。

数据库中有一堆行,涵盖了几个月的数据。

目标是制作一个显示每日平均值的查询。

所以一个超级简单的例子是:

BookedDateTime           | PickupDateTime
2014-06-09 12:48:00.000    2014-06-09 12:45:00.000
2014-06-09 12:52:00.000    2014-06-09 12:58:00.000    
2014-06-10 20:23:00.000    2014-06-10 20:28:00.000
2014-06-10 22:13:00.000    2014-06-10 22:13:00.000

2014-06-09 ((-3 + 6) / 2) = 平均值为 00:03:00.000(3 分钟)

2014-06-10 ((5 + 0) / 2) = 平均值为 00:02:30.000(2.5 分钟)

这可能吗,还是我需要在代码中进行一些数字运算(即 C#)?

任何指针将不胜感激。

【问题讨论】:

  • 预约时间怎么比提货时间早,我是说你的例子的第一条记录
  • 预订时间是乘客指定他们想要接机的时间。接送时间是出租车司机实际到达的时间。所以这意味着 PickupDateTime 值可能是正数或负数。谢谢。

标签: sql tsql date datetime


【解决方案1】:

我认为这样可以:

select Convert(date, BookedDateTime) as Date, AVG(datediff(minute, BookedDateTime, PickupDateTime)) as AverageTime
    from tablename 
    group by Convert(date, BookedDateTime)  
    order by Convert(date, BookedDateTime) 

【讨论】:

  • 谢谢。至于所有答案,我得到以下错误,这一定与数据而不是查询有关:'算术溢出错误将表达式转换为数据类型 int。'
  • 我认为我收到的错误是由于以下问题造成的:“要计算平均平均值,服务器需要能够首先对所有整数求和,因此您需要平均的数据类型能够存储这些值的总和,即使返回的答案在 int 的范围内。”每天有很多行,这意味着这个数字很容易大于一个 int。有什么方法可以默认使用 bigint 来代替计算?
  • 您可以在调用 AVG 之前将表达式转换为 bigint : AVG(Convert(bigint, datediff(minute, BookedDateTime, PickupDateTime)))
  • 非常感谢。您是第一个回应,这非常适合我的需求。因此,我将其授予选定的答案。我遇到的问题是由于某些日期在导入时默认为 1970 年。一旦我从数据中删除了这些,一切都运行良好。非常感谢!
【解决方案2】:

以预定时间的当天作为报告日期:

select
    convert(date, BookedDateTime) as day,
    AVG(DATEDIFF(minute, PickupDateTime, BookedDateTime)) as avg_minutes
from bookings
group by convert(BookedDateTime, datetime, 101) 

【讨论】:

  • 谢谢。至于所有答案,我得到以下错误,这一定与数据而不是查询有关:'算术溢出错误将表达式转换为数据类型 int。'
  • 再次感谢您的帮助。我遇到的问题是由于某些日期在导入时默认为 1970 年。从数据中删除这些后,我不再收到错误消息!
【解决方案3】:

这可以通过找出每一行的差异,将它们相加并除以行数来完成。

在 SQLSERVER 中,它将如下所示。

SELECT SUM(DATEDIFF(MINUTE,BookedDateTime,PickupDateTime)) * 1.0 
           / (SELECT COUNT(*) * 1.0 FROM MyTable)
FROM MyTable

【讨论】:

    【解决方案4】:

    请试试这个:

    IF OBJECT_ID(N'tempdb..#TEMP') > 0
        BEGIN
           DROP TABLE #TEMP
        END
    CREATE TABLE #TEMP(BookedDateTime DateTime,
                    PickupDateTime DateTime)
    INSERT INTO #TEMP
    VALUES
    ('2014-06-09 12:48:00.000', '2014-06-09 12:45:00.000'),
    ('2014-06-09 12:52:00.000', '2014-06-09 12:58:00.000'), 
    ('2014-06-10 20:23:00.000', '2014-06-10 20:28:00.000'),
    ('2014-06-10 22:13:00.000', '2014-06-10 22:13:00.000'),
    ('2014-06-10 23:59:00.000', '2014-06-11 00:01:00.000')
    
    SELECT CAST(BookedDateTime AS DATE) AS YMDDate,
          CONVERT(CHAR(8), DATEADD(second, AVG(DATEDIFF(s, BookedDateTime, PickupDateTime)), 0), 108) [hh:mi:ss],
          CONVERT(CHAR(15), DATEADD(second, AVG(DATEDIFF(s, BookedDateTime, PickupDateTime)), 0), 114) [hh:mi:ss:mmm(24h)]
    FROM #TEMP
    GROUP BY CAST(BookedDateTime AS DATE)
    

    【讨论】:

    • 非常感谢。这很好用。至于所有答案,我收到以下错误,这必须与数据而不是查询有关:“将表达式转换为数据类型 int 的算术溢出错误。”我查看了日期,但我看不到任何看起来不正确的日期......
    • 再次感谢您的帮助。我遇到的问题是由于某些日期在导入时默认为 1970 年。从数据中删除这些后,我不再收到错误消息!
    猜你喜欢
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    相关资源
    最近更新 更多