HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlMinor

Standard Deviation for Times

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
timesfordeviationstandard

Problem

Is there a T-SQL coding best practice to get an accurate standard deviation value for a group of times? STDEV doesn't like the time data type. I'm thinking that maybe a conversion to minutes as an integer, but a conversion from/to what? Any suggestions?

Solution

You can convert a time value to a corresponding number of desired time units by using the DATEDIFF() and DATEDIFF_BIG() functions:

DATEDIFF(MINUTE, CAST('00:00' AS time), YourTimeColumn) AS Minutes

DATEDIFF(SECOND, CAST('00:00' AS time), YourTimeColumn) AS Seconds

DATEDIFF(MILLISECOND, CAST('00:00' AS time), YourTimeColumn) AS Milliseconds


Basically, you are just obtaining the difference, in the given units, between the timestamp of 00:00:00.0000000 and your time value.

You can put the entire expression inside STDEV:

STDEV(DATEDIFF(MINUTE, CAST('00:00' AS time), YourTimeColumn))


That, of course, will give you the deviation in minutes. If you need to convert it back to time, you can do it by applying DATEADD() to the STDEV result:

DATEADD(
  MINUTE
, CAST('00:00' AS time)
, STDEV(
    DATEDIFF(
      MINUTE
    , CAST('00:00' AS time)
    , YourTimeColumn
    )
  )
)


The final expression becomes quite cumbersome this way. You can try simplifying it by defining some of the intermediate expressions as columns. One way is to use CROSS APPLY. For instance, here is how you can define and use a temporary computed column for the DATEDIFF result:

SELECT
  ...
  DATEADD(MINUTE, CAST('00:00' AS time), STDEV(tmp.TimeMinutes)) AS TimeStDev,
  ...
FROM
  dbo.YourTable AS data
  CROSS APPLY
  (
    SELECT
      DATEDIFF(MINUTE, CAST('00:00' AS time), data.YourTimeColumn)
  ) AS tmp (TimeMinutes)
  ...
WHERE
  ...
;

Code Snippets

DATEDIFF(MINUTE, CAST('00:00' AS time), YourTimeColumn) AS Minutes

DATEDIFF(SECOND, CAST('00:00' AS time), YourTimeColumn) AS Seconds

DATEDIFF(MILLISECOND, CAST('00:00' AS time), YourTimeColumn) AS Milliseconds
STDEV(DATEDIFF(MINUTE, CAST('00:00' AS time), YourTimeColumn))
DATEADD(
  MINUTE
, CAST('00:00' AS time)
, STDEV(
    DATEDIFF(
      MINUTE
    , CAST('00:00' AS time)
    , YourTimeColumn
    )
  )
)
SELECT
  ...
  DATEADD(MINUTE, CAST('00:00' AS time), STDEV(tmp.TimeMinutes)) AS TimeStDev,
  ...
FROM
  dbo.YourTable AS data
  CROSS APPLY
  (
    SELECT
      DATEDIFF(MINUTE, CAST('00:00' AS time), data.YourTimeColumn)
  ) AS tmp (TimeMinutes)
  ...
WHERE
  ...
;

Context

StackExchange Database Administrators Q#297664, answer score: 8

Revisions (0)

No revisions yet.