如何计算多行中格式为 VARCHAR 的日期的平均值?

How do I calculate averages of dates formatted as VARCHAR from multiple rows?

我遇到了一个问题,我是 运行 针对数据库的脚本,以获取需要转换为日期时间的多个 VARCHAR 之间的平均差异,然后取所有结果之间的平均值。

我的代码是:

SELECT YEAR(b.DateAcknow),AVG(datediff(dd,convert(datetime,b.DateAssign),
convert(datetime,b.DateResolv))) as DayAverage, 
AVG(datediff(hh,convert(datetime,b.TimeAcknow),  
convert(datetime,b.TimeResolv))) as HourAverage

FROM      table AS b              
WHERE     (x = y) 
AND YEAR(DateResolv) >= 2006
AND YEAR(DateResolv) < 2016
AND  b.resolution <>''

GROUP BY YEAR(b.DateAcknow)
ORDER BY YEAR(b.DateAcknow)`

我得到的结果似乎没有意义,更不用说它包括 1900,它不在我的 where 子句的参数范围内

这里是:

NULL        42          NULL
1900        0           12
2006        7           -5
2007        6           1
2008        7           1
2009        4           1
2010        2           0
2011        2           0
2012        2           0
2013        2           0
2014        2           0
2015        2           0

我把 VARCHAR 转换错了吗?

我怀疑 2010 年至 2015 年数千条条目的平均值也都是相同的 2 天 0 小时,所以要么我做错了什么,要么数据不好。

您正在按 DateResolv 过滤并按 DateAcknow 分组。

按相同字段和 NULL 进行过滤和分组,范围外的值应该消失。

您可能想要去掉聚合部分,只需要 运行:

SELECT YEAR(b.DateAcknow)
, convert(datetime,b.DateAssign) AS DateAssignDateTime
, convert(datetime,b.DateResolv) AS DateResolveDateTime
, datediff(dd,convert(datetime,b.DateAssign), convert(datetime,b.DateResolv)) AS AssignResolveDayDiff
, convert(datetime,b.TimeAcknow) AS TimeAcknowDateTime
, convert(datetime,b.TimeResolv) AS TimeResolveDateTime
, datediff(hh,convert(datetime,b.TimeAcknow), convert(datetime,b.TimeResolv)) AS AcknowResolveHourDiff
FROM      table AS b              
WHERE     (x = y) 
AND YEAR(DateAcknow) >= 2006
AND YEAR(DateAcknow) < 2016
AND  b.resolution <>''
ORDER BY YEAR(b.DateAcknow)

首先要确保您的所有转化都有意义。然后你会更好地理解你实际平均的是什么。

之后,如果一切正常,那么您的查询应该可以正常工作(不过,请检查 mxix 是否从

...
AND YEAR(DateResolv) >= 2006
AND YEAR(DateResolv) < 2016
...

...
AND YEAR(b.DateAcknow) >= 2006
AND YEAR(b.DateAcknow) < 2016
...

对你有意义。

如果您希望提高输出的精度,请尝试像这样转换日期差异: 旧:AVG(datediff(dd,convert(datetime,b.DateAssign), convert(datetime,b.DateResolv)))

新:AVG(Convert(Decimal(10, 5), datediff(dd,convert(datetime,b.DateAssign), convert(datetime,b.DateResolv))))

您的旧查询是平均天数,四舍五入到最接近的整数值,为您提供类似于“2”的值。这项新调整将为您提供类似“1.51235”天的答案。

由于有 10 万条差异记录(正负),如果平均值服从正态分布或均匀分布,则平均值很可能接近于零。也试试: AVG(Convert(Decimal(10, 5), ABS(datediff(dd,convert(datetime,b.DateAssign), convert(datetime,b.DateResolv)))))

如果你想要绝对差异。如果您的旧数据的值为“5、-3、4、-1、3”,那么旧方法将产生 2 的平均值,但如果您使用 "ABS" 函数处理它们,它将改变值为“5, 3, 4, 1, 3”,并将结果平均值向 ++ 方向移动(此处,如果您也进行了十进制转换,则它变为“3”或“3.2”)。

My intention is to display for each year what the average response time is in Days and Hours. – obizues

假设:

  1. DateAcknow 是一个带有空时间戳的 varchar 日期(例如,“2011/01/15”)
  2. TimeAcknow 是 DateAcknow 对应的 varchar 时间(例如,“15:35”)
  3. DateResolve 是一个带有空时间戳(例如“2011/01/16”)的 varchar 日期,它始终大于或等于 DateAcknow
  4. TimeResolve 是 DateResolve 对应的 varchar 时间(例如,“13:47”)
  5. 你想平均总小时差(使用上面的例子,这条记录的小时差是 22)

如果您需要有关 varchar 日期格式和转换函数的帮助,请参阅: http://msdn.microsoft.com/en-us/library/ms187928.aspx

以下方法应该可以实现您的意图:

SELECT YEAR(b.DateAcknow)
, AVG(DateDiff(Day, Convert(datetime, b.DateAcknow) + convert(datetime, b.TimeAcknow), Convert(datetime, b.DateResolv) + Convert(datetime, b.TimeResolve)))  AS AvgDaysDifference
, AVG(DateDiff(Hour, Convert(datetime, b.DateAcknow) + convert(datetime, b.TimeAcknow), Convert(datetime, b.DateResolv) + Convert(datetime, b.TimeResolve)))  AS AvgHoursDifference
FROM      table AS b              
WHERE (x = y) AND YEAR(DateAcknow) >= 2006 AND YEAR(DateAcknow) < 2016
   AND  b.resolution <>''
GROUP BY YEAR(b.DateAcknow)

如果关于您的数据和您的意图的假设是正确的,那么应该这样做。不清楚的地方很难帮忙