sql - 如何获取单个列的两个日期之间的天数的平均值

时间:2014-08-10 21:49:48

标签: sql sql-server-2012

我认为这很容易,但我能想到的唯一方法是临时表。基本上我有一列叫做'myDate'这是一个日期时间列我想知道的是所有这些行的平均天数差异。

所以基本上结果就是这个

1/1/2014
1/14/2014
1/20/2014

所以基本上我想知道平均值是9.5天。 1/1 - 1/14是13天,14/20是6天,所以19/2是9.5

我的基本查询是select myDate from myTable

2 个答案:

答案 0 :(得分:0)

平均值是最大值减去最小值除以天数减去1。所以,你可以得到它:

select datediff(day, min(myDate), max(myDate)) / cast(count(*) - 1 as float)
from temp;

如果您想要真正小心,可以防止潜在的被零除错误:

select (case when count(*) > 1
             then datediff(day, min(myDate), max(myDate)) / cast(count(*) - 1 as float)
             else 0
        end)
from temp;

答案 1 :(得分:0)

你可能不需要临时表,但我不相信上述方法适用于所有情况。您的要求是将一行的日期与下一行的日期进行比较,但没有迹象表明“下一行”日期'始终大于上一个日期。如果一对日期产生来自datediff()的否定结果,则这些日期之间的持续时间忽略该符号,即是绝对值。例如如果我们计算datediff(day,2014-01-02,2013-01-03)结果是-364,但实际上持续时间是364,因为我们应该在datediff()函数中翻转日期序列。

|     MYDATE |    NXTDATE | RAWDIFF | DAYDIFF |
|------------|------------|---------|---------|
| 2013-01-01 | 2014-01-02 |     366 |     366 |
| 2014-01-02 | 2013-01-03 |    -364 |     364 |
| 2013-01-03 | 2014-01-27 |     389 |     389 |
| 2014-01-27 | 2013-01-28 |    -364 |     364 |
| 2013-01-28 | 2014-01-29 |     366 |     366 |
| 2014-01-29 | 2014-06-30 |     152 |     152 |
| 2014-06-30 |     (null) |  (null) |  (null) |

因此,由于日期可能会前后移动,因此按总跨度来衡量平均持续时间可能会产生误导。

|     MIN_DT |     MAX_DT | MAX_MIN_SPAN | SPAN_AVG | SUM_DAYDIFFS | COUNT | TRUE_AVG |
|------------|------------|--------------|----------|--------------|-------|----------|
| 2013-01-01 | 2014-06-30 |          545 | 90.83333 |         2001 |     6 |    333.5 |

用于此的查询:

SELECT
      MIN(mydate)                                                       min_dt
    , MAX(mydate)                                                       max_dt
    , DATEDIFF(DAY, MIN(mydate), MAX(mydate))                           max_min_span
    , DATEDIFF(DAY, MIN(mydate), MAX(mydate)) / (COUNT(daydiff) * 1.0)  span_avg

    , SUM(daydiff)                                                      sum_daydiffs
    , COUNT(daydiff)                                                    count_daydiffs
    , SUM(daydiff) / (COUNT(daydiff) * 1.0)                             true_avg
FROM (
            SELECT
                  mydate
                , ABS(DATEDIFF(DAY, mydate, LEAD(mydate) OVER (ORDER BY (SELECT 1)) )) AS daydiff
            FROM mytable
      ) sq
;

SELECT
        mydate
      , lead(mydate) over(order by (select 1)) nxtdate
      , DATEDIFF(DAY, mydate, LEAD(mydate) OVER (ORDER BY (SELECT 1)) )      AS rawdiff
      , ABS(DATEDIFF(DAY, mydate, LEAD(mydate) OVER (ORDER BY (SELECT 1)) )) AS daydiff
FROM mytable
;

请参阅:http://sqlfiddle.com/#!6/a7cdc/4