我有一个查询
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运算符无效。
我该如何计算?
答案 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