11

How can I avg(time(4)) in the following query:

  select top 10 avg(e.Duration) from TimeTable e

I'm getting the following error:

Operand data type time is invalid for avg operator.

Duration is type time(4) such as:

Duration
-------------
00:00:10.0000
3
  • TIME represents a point in time. If you're trying to store a duration, store it as an integer. Commented Aug 3, 2012 at 2:53
  • @AaronBertrand: Hi, I can't store it as an int...it's not my database.
    – genxgeek
    Commented Aug 3, 2012 at 3:20
  • Then you'll need to perform a convert or other date operations every single time. You should tell the database owner that they're paying a hefty price to store a duration using a nice format. Commented Aug 3, 2012 at 3:57

4 Answers 4

18

You can use DateDiff( ms, '00:00:00', e.Duration ) to convert the time into an integer number of milliseconds. Use that for your aggregate, then convert the result back, e.g. Cast( DateAdd( ms, 1234, '00:00:00' ) as Time ).

2
  • What is ms here? Commented Sep 8, 2016 at 13:05
  • 1
    Per the documentation, it indicates that the difference between the date/times should be returned in units of milliseconds.
    – HABO
    Commented Sep 11, 2016 at 3:46
9

Improving off of HABO answer:

select top 10
Cast(DateAdd( ms,avg(DateDiff( ms, '00:00:00', e.Duration)), '00:00:00' )  as time) as 'avg duration' 
from TimeTable e
3

Addition to HABO's and Rafi's answers.

For my case, I had to cast the value of the DATEDIFF to a bigint because my value grew too large and caused an arithmetic overflow error.

CAST(DATEADD( ms,AVG(CAST(DATEDIFF( ms, '00:00:00', ISNULL(e.Duration, '00:00:00')) as bigint)), '00:00:00' )  as TIME) as 'avg_time'
1

Well it seems like time is an invalid type for the avg() method. Refer here for a list of valid data types.

Also, it seems like you need a group of values for this, which would negate the need for top 10 with your current query.

Not the answer you're looking for? Browse other questions tagged or ask your own question.