SQL Server 2008 - 平均值的计算。定时

时间:2012-07-28 09:13:10

标签: sql sql-server-2008

我有一个查询

select
  *,
  right(
    convert(varchar, cast(JOB_DONE_time-JOB_send_time as datetime), 121),
    12
  ) [TimeTaken]
from dbo.insert_data
order by job_id desc  

此查询的结果类似于

JOB_ID     JOB_DONE_TIME            JOB_SEND_TIME            TimeTaken
---------  -----------------------  -----------------------  ------------
001-99900  2011-12-28 13:36:57.860  2011-12-28 13:36:57.593  00:00:00.267
001-99800  2011-12-28 13:36:57.843  2011-12-28 13:36:57.593  00:00:00.250
001-99700  2011-12-28 13:36:57.687  2011-12-28 13:36:57.547  00:00:00.140
001-99600  2011-12-28 13:36:57.593  2011-12-28 13:36:57.547  00:00:00.047
001-99500  2011-12-28 13:36:57.563  2011-12-28 13:36:57.437  00:00:00.127
001-99400  2011-12-28 13:36:57.547  2011-12-28 13:36:57.437  00:00:00.110
001-99300  2011-12-28 13:36:57.483  2011-12-28 13:36:57.377  00:00:00.107
001-99200  2011-12-28 13:36:57.437  2011-12-28 13:36:57.377  00:00:00.060
001-99100  2011-12-28 13:36:57.407  2011-12-28 13:36:57.187  00:00:00.220
001-99000  2011-12-28 13:36:57.360  2011-12-28 13:36:57.187  00:00:00.173
001-9900   2011-12-28 13:32:22.657  2011-12-28 13:32:22.500  00:00:00.127

并且通过此查询我有TimeTaken列。现在我想计算加法和平均值。列timetaken。我尝试使用SUM()函数,但它给了我错误:

  

消息8117,级别16,状态1,行1操作数数据类型varchar是   对于sum运算符无效。

我该如何计算?

4 个答案:

答案 0 :(得分:1)

正如您已经被告知的那样,问题与您尝试将AVG()SUM()应用于字符串列这一事实有关,而实际上您只能使用这些函数在数字列上。

作为特定于SQL Server的解决方案,您可以暂时将JOB_DONE_time - JOB_send_time的结果转换为float,计算AVG()和/或SUM()然后将结果转换回来到datetime,然后到varchar,然后提取最后12个字符,就像你现在在减法的非聚合结果上做的那样。

这是我的意思的一个例子:

SELECT
  JOB_ID,
  JOB_DONE_TIME,
  JOB_SEND_TIME,
  TimeTaken      = RIGHT(CONVERT(varchar(30), CAST(    TimeTakenFP          AS datetime), 121), 12),
  AvgTimeTaken   = RIGHT(CONVERT(varchar(30), CAST(AVG(TimeTakenFP) OVER () AS datetime), 121), 12),
  TotalTimeTaken = RIGHT(CONVERT(varchar(30), CAST(SUM(TimeTakenFP) OVER () AS datetime), 121), 12)
FROM (
  SELECT
    *,
    TimeTakenFP = CAST(JOB_DONE_TIME - JOB_SEND_TIME AS float)
  FROM insert_data
) s
;

对于您的示例数据,上面的查询返回以下结果集:

JOB_ID    JOB_DONE_TIME           JOB_SEND_TIME           TimeTaken    AvgTimeTaken TotalTimeTaken
--------- ----------------------- ----------------------- ------------ ------------ --------------
001-99900 2011-12-28 13:36:57.860 2011-12-28 13:36:57.593 00:00:00.267 00:00:00.150 00:00:01.657
001-99800 2011-12-28 13:36:57.843 2011-12-28 13:36:57.593 00:00:00.250 00:00:00.150 00:00:01.657
001-99700 2011-12-28 13:36:57.687 2011-12-28 13:36:57.547 00:00:00.140 00:00:00.150 00:00:01.657
001-99600 2011-12-28 13:36:57.593 2011-12-28 13:36:57.547 00:00:00.047 00:00:00.150 00:00:01.657
001-99500 2011-12-28 13:36:57.563 2011-12-28 13:36:57.437 00:00:00.127 00:00:00.150 00:00:01.657
001-99400 2011-12-28 13:36:57.547 2011-12-28 13:36:57.437 00:00:00.110 00:00:00.150 00:00:01.657
001-99300 2011-12-28 13:36:57.483 2011-12-28 13:36:57.377 00:00:00.107 00:00:00.150 00:00:01.657
001-99200 2011-12-28 13:36:57.437 2011-12-28 13:36:57.377 00:00:00.060 00:00:00.150 00:00:01.657
001-99100 2011-12-28 13:36:57.407 2011-12-28 13:36:57.187 00:00:00.220 00:00:00.150 00:00:01.657
001-99000 2011-12-28 13:36:57.360 2011-12-28 13:36:57.187 00:00:00.170 00:00:00.150 00:00:01.657
001-9900  2011-12-28 13:32:22.657 2011-12-28 13:32:22.500 00:00:00.157 00:00:00.150 00:00:01.657

此查询使用windowed聚合函数计算聚合结果,以便您可以查看聚合结果和非聚合结果。我只使用了窗口函数,因为我想向您展示如何将显示时间的方法应用于非聚合和聚合结果,以便您可以看到表达式的哪个部分根据您需要的结果类型而变化转换为时间表示。实际上,如果这是您的要求,您可以使用“正常”汇总结果(并在必要时进行分组)。

您可以使用查询at SQL Fiddle的“实时”演示。

答案 1 :(得分:0)

在sql中使用avg函数,它将为列提供平均值

SELECT AVG(column name) FROM tabelname;

和像这样的总和使用

 SELECT sum(column name)  FROM tabelname;

答案 2 :(得分:0)

您可以确定完成时间列和发送时间列的约会时间(以毫秒为单位),然后平均或总结这些结果

select sum(datediff(ms, JOB_send_time, JOB_DONE_time)) as SUM_Timing
,      avg(datediff(ms, JOB_send_time, JOB_DONE_time)) as AVG_Timing
from   dbo.insert_data

答案 3 :(得分:0)

我认为(对不起,现在不能试试)你需要DATEDIFF。

在你的情况下:

select avg(DATEDIFF(Millisecond, JOB_DONE_time, JOB_send_time)) from dbo.insert_data