我需要找到按记录的user_id
分组的记录之间的平均天数。
该表的PK为eval_id
,因此我的列为eval_id
,user_id
和quality_date
。输出只是user_id
和平均天数:
每个用户没有一致的记录数,平均值是与用户相关的所有记录的一个值。到目前为止,试图找到一种动态方法是不成功的。
我正在使用SQL Server 2012
,SSMS。
答案 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