【问题标题】:Average Days between Records by User_IDUser_ID 记录之间的平均天数
【发布时间】:2014-02-27 12:55:41
【问题描述】:

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

表的 PK 是eval_id,所以我的列是eval_iduser_idquality_date。输出将只是 user_id 和平均天数:

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

我正在使用SQL Server 2012,SSMS。

【问题讨论】:

  • 写表的查询不是更好

标签: sql sql-server tsql


【解决方案1】:

原答案:

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

编辑 Jason 的评论:

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。

【讨论】:

  • 我对上述内容的唯一担心是您已经设置了可能的除以零条件,因为您可能只有一条记录。可以通过 (count(*) - 1.0) 上的 NULLIF 条件(或将值默认为 1 的情况)来解决这个问题。
  • 到那时@Jason,我确实遇到了。我添加了一个“Having”子句来控制它。好收获!
  • @JasonWhisman 是完全正确的。我已经添加到我原来的答案中。
【解决方案2】:

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

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() 函数。

【讨论】:

  • 谢谢!我知道你要去哪里。我试过了,我得到一个“无法对包含聚合或子查询的表达式执行聚合函数”。
  • @BumpML 。 . .天哪,我觉得自己很愚蠢。 sum() 是完全没有必要的,因为 max()min() 之间的区别。
【解决方案3】:

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

;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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 2021-09-22
    相关资源
    最近更新 更多