Reputation: 101
I have a query
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
and result of this query is like
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
and by this query I have got TimeTaken
column. Now I want to calculate addition and avg. of column timetaken
. I have tried with SUM()
function but it gives me error:
Msg 8117, Level 16, State 1, Line 1 Operand data type varchar is invalid for sum operator.
How can I calculate it???
Upvotes: 3
Views: 662
Reputation: 77707
As you've already been told, the issue has to do with the fact that you are trying to apply AVG()
or SUM()
to a string column, while in fact you can only use those functions on numeric columns.
As a very SQL Server-specific solution, you could temporarily cast the result of JOB_DONE_time - JOB_send_time
to float
, calculate AVG()
and/or SUM()
then convert the results back to datetime
, then to varchar
, then extract the last 12 characters, like you are doing now on the non-aggregated results of the subtraction.
Here's an example of what I mean:
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
;
For your sample data, the above query returns the following result set:
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
This query calculates the aggregated results using windowed aggregate functions, so that you could see both aggregated and non-aggregated results. I only used windowed functions because I wanted to show you how your method of displaying the time can be applied to both non-aggregated and aggregated results, so that you could see which part of the expression changes depending on what kind of the result you need to convert to the time representation. In reality you may use "normal" aggregated results (and grouping, if necessary), if that's your requirement.
You can play with a "live" demonstration of the query at SQL Fiddle.
Upvotes: 1
Reputation: 60034
I think (sorry, can't try out now) that you need DATEDIFF.
In your case:
select avg(DATEDIFF(Millisecond, JOB_DONE_time, JOB_send_time)) from dbo.insert_data
Upvotes: 0
Reputation: 42483
You can determine the datediff in milliseonds for the done and send time columns and then avg or sum those results
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
Upvotes: 0
Reputation: 707
use avg function in sql which will give you avg for column
SELECT AVG(column name) FROM tabelname;
and for sum use like this
SELECT sum(column name) FROM tabelname;
Upvotes: 0