如何计算多行中格式为 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
假设:
- DateAcknow 是一个带有空时间戳的 varchar 日期(例如,“2011/01/15”)
- TimeAcknow 是 DateAcknow 对应的 varchar 时间(例如,“15:35”)
- DateResolve 是一个带有空时间戳(例如“2011/01/16”)的 varchar 日期,它始终大于或等于 DateAcknow
- TimeResolve 是 DateResolve 对应的 varchar 时间(例如,“13:47”)
- 你想平均总小时差(使用上面的例子,这条记录的小时差是 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)
如果关于您的数据和您的意图的假设是正确的,那么应该这样做。不清楚的地方很难帮忙
我遇到了一个问题,我是 运行 针对数据库的脚本,以获取需要转换为日期时间的多个 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
假设:
- DateAcknow 是一个带有空时间戳的 varchar 日期(例如,“2011/01/15”)
- TimeAcknow 是 DateAcknow 对应的 varchar 时间(例如,“15:35”)
- DateResolve 是一个带有空时间戳(例如“2011/01/16”)的 varchar 日期,它始终大于或等于 DateAcknow
- TimeResolve 是 DateResolve 对应的 varchar 时间(例如,“13:47”)
- 你想平均总小时差(使用上面的例子,这条记录的小时差是 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)
如果关于您的数据和您的意图的假设是正确的,那么应该这样做。不清楚的地方很难帮忙