【问题标题】:How do I calculate averages of dates formatted as VARCHAR from multiple rows?如何从多行计算格式化为 VARCHAR 的日期的平均值?
【发布时间】:2016-05-04 14:29:38
【问题描述】:

我遇到了一个问题,我正在针对数据库运行脚本以获取需要转换为 DateTimes 的多个 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

我将VARCHARs 转换错了吗?

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

【问题讨论】:

  • 我不确定你的意思。我的目的是显示每年的平均响应时间(以天和小时为单位)。
  • 如果没有示例数据,就很难看出发生了什么……难道自 2010 年以来所有日期都存储为空时间戳?这可以解释 0 小时的差异。至于天数,如果管理层希望在 2 天后关闭呼叫,很可能大多数都是这样,导致平均 2 天(如果您平均整数,我不知道 AVG 是否返回除 int 之外的任何内容? )
  • 另外,虽然您的措辞似乎暗示了这一点,但您的日子和时间并不属于同一时间跨度。
  • @oerkelens 尽管它们是两个独立的字段,但它们的时间跨度相同。一个只是日期(DateAssign-DateResolv),另一个只是 24 小时制时间(TimeAcknow-TimeResolv)。
  • 那么 DateAssign 和 DateAcknow 一样吗?否则,它们是两个不同的时间跨度,一个以天表示,另一个以小时表示。请注意,小时数应该返回总小时数,不是时间跨度的“小时”部分(因此两天为 48 小时)。

标签: sql datetime varchar datediff


【解决方案1】:

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

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

【讨论】:

  • 所以我进行了适当的更改以摆脱 NULL 值 - 但我仍然有每个条目的 2 天平均值和 0 小时平均值。
【解决方案2】:

您可能想要删除聚合部分并运行:

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
...

对你有意义。

如果您希望提高输出的精度,请尝试像这样转换您的 datediff: 老: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")。

【讨论】:

  • 运行你所建议的确实会返回正确的数据。
  • 那么你能发现问题吗?也许如果您要发布此查询的结果以及聚合的预期结果,我可以发现逻辑错误。您可能需要对差异使用 ABS 函数,和/或将它们转换为十进制类型,然后再进行平均以获得“适当”的结果。
  • 它包含敏感数据结果,很遗憾我不能这样做。它还返回了大约 100,000 条记录。即使四舍五入不是小数点,它们都是平均 2 天零 0 小时的几率确实是强力球几率。
  • 您可能希望输出记录数最少的年份的值,并在电子表格中手动进行数学运算以检查它。 (另外,请参阅上面对我的答案的修改)
【解决方案3】:

我的目的是显示每年的平均反应 时间以天和小时为单位。 – obizues

假设:

  1. DateAcknow 是带有空时间戳的 varchar 日期(例如,“2011/01/15”)
  2. TimeAcknow 是 DateAcknow 对应的 varchar 时间(例如,“15:35”)
  3. DateResolve 是一个带有空时间戳的 varchar 日期(例如,“2011/01/16”),它始终大于或等于 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)

如果对您的数据和意图的假设是正确的,则应该这样做。不清楚时很难提供帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-23
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 2014-06-04
    相关资源
    最近更新 更多