User_ID记录之间的平均天数

时间:2014-02-27 12:55:41

标签: sql sql-server tsql

我需要找到按记录的user_id分组的记录之间的平均天数。

该表的PK为eval_id,因此我的列为eval_iduser_idquality_date。输出只是user_id和平均天数:

每个用户没有一致的记录数,平均值是与用户相关的所有记录的一个值。到目前为止,试图找到一种动态方法是不成功的。

我正在使用SQL Server 2012,SSMS。

3 个答案:

答案 0 :(得分:1)

您可以通过取总跨度并除以1减去记录数来获得平均值。

select user_id,
       (case when count(*) > 1
             then datediff(day, min(quality_date), max(quality_date)) / (count(*) - 1.0)
        end) as AvgTimeBetween
from eval
group by user_id;

有更难的方法进行计算,例如计算每个范围(使用lag()说)然后使用avg()函数。

答案 1 :(得分:1)

原始答案:

select user_id, datediff(day, min(quality_date), max(quality_date)) / (count(*) - 1.0)
from eval
group by user_id

根据杰森的评论编辑:

select user_id, datediff(day, min(quality_date), max(quality_date)) / NULLIF((count(*) - 1.0), 0)
from eval
group by user_id
如果用户只有一条记录,

将避免除以零错误。该用户在平均列中将为NULL。

select user_id, 
  case 
    when count(*) = 1 then 1
    else datediff(day, min(quality_date), max(quality_date)) / (count(*) - 1.0)
  end
from eval
group by user_id

也可以避免错误,但为受影响的用户提供1而不是NULL。

答案 2 :(得分:0)

我觉得你想要一个用户的两个连续记录之间的差异的平均值。我的解决方案将为您提供,除非用户只有一条记录。

;WITH dummy_data(evalId, userId, qualityTime)
AS
(
    SELECT 1, 123, DATEADD(DAY, 0, '2012-12-12')
    UNION ALL SELECT 2, 123, DATEADD(DAY, 2, '2012-12-12')
    UNION ALL SELECT 3, 123, DATEADD(DAY, 5, '2012-12-12')
    UNION ALL SELECT 4, 123, DATEADD(DAY, 7, '2012-12-12')
    UNION ALL SELECT 5, 123, DATEADD(DAY, 10, '2012-12-12')
    UNION ALL SELECT 6, 123, DATEADD(DAY, 14, '2012-12-12')
    UNION ALL SELECT 7, 123, DATEADD(DAY, 15, '2012-12-12')
    UNION ALL SELECT 8, 123, DATEADD(DAY, 16, '2012-12-12')
    UNION ALL SELECT 9, 123, DATEADD(DAY, 20, '2012-12-12')
    UNION ALL SELECT 10, 123, DATEADD(DAY, 26, '2012-12-12')

    -- Avg 2
    UNION ALL SELECT 11, 124, DATEADD(DAY, 0, '2012-12-12')
    UNION ALL SELECT 12, 124, DATEADD(DAY, 1, '2012-12-12')
    UNION ALL SELECT 13, 124, DATEADD(DAY, 2, '2012-12-12')
    UNION ALL SELECT 14, 124, DATEADD(DAY, 3, '2012-12-12')
    UNION ALL SELECT 15, 124, DATEADD(DAY, 4, '2012-12-12')
    UNION ALL SELECT 16, 124, DATEADD(DAY, 5, '2012-12-12')
    UNION ALL SELECT 17, 124, DATEADD(DAY, 6, '2012-12-12')
    UNION ALL SELECT 18, 124, DATEADD(DAY, 7, '2012-12-12')
    UNION ALL SELECT 19, 124, DATEADD(DAY, 8, '2012-12-12')
    UNION ALL SELECT 20, 124, DATEADD(DAY, 9, '2012-12-12')

    -- Avg 1
    UNION ALL SELECT 21, 126, DATEADD(DAY, 0, '2012-12-12')
    UNION ALL SELECT 22, 126, DATEADD(DAY, 2, '2012-12-12')
    UNION ALL SELECT 23, 126, DATEADD(DAY, 4, '2012-12-12')
    UNION ALL SELECT 24, 126, DATEADD(DAY, 6, '2012-12-12')
    UNION ALL SELECT 25, 126, DATEADD(DAY, 8, '2012-12-12')
    UNION ALL SELECT 26, 126, DATEADD(DAY, 10, '2012-12-12')
    UNION ALL SELECT 27, 126, DATEADD(DAY, 12, '2012-12-12')
    UNION ALL SELECT 28, 126, DATEADD(DAY, 14, '2012-12-12')
    UNION ALL SELECT 29, 126, DATEADD(DAY, 16, '2012-12-12')
    UNION ALL SELECT 30, 126, DATEADD(DAY, 18, '2012-12-12')

    -- Will not show
    UNION ALL SELECT 31, 127, DATEADD(DAY, 0, '2012-12-12')
)
,eval
AS
(
    SELECT  *
            ,ROW_NUMBER() OVER (PARTITION BY userId ORDER BY qualityTime) AS rowNumber
    FROM    dummy_data
)

SELECT  e1.userId
        ,SUM(DATEDIFF(DAY, e1.qualityTime, e2.qualityTime)) * 1.0 / COUNT(e1.qualityTime) AS calculated_average
        ,AVG(DATEDIFF(DAY, e1.qualityTime, e2.qualityTime)) AS average
FROM    eval e1
JOIN    eval e2
    ON  e1.userId = e2.userId
    AND e1.rowNumber = e2.rowNumber - 1
GROUP BY e1.userId