鉴于有两个表:
每个user
都可以有一个或多个事件。
每个event
只能由一个用户拥有。
我将以下查询放在一起,以平均事件和用户的相应created_at时间戳之间的差异。
SELECT
(
SELECT AVG(TIMESTAMPDIFF(DAY, users.created_at, events.created_at))
FROM users
INNER JOIN events
ON users.id = events.user_id
WHERE events.created_at IS NOT NULL
AND users.created_at IS NOT NULL
) AS "Difference between created_at of user and created_at of user's first event, averaged across all users."
然而,如何只包括FIRST重叠,其中event.created_at的时间戳最低?我相信目前,代码将采用每个时间戳和created_at之间的差异,并将其平均。我想要完成的是为每个用户在他/她的第一个创建的事件之间获得差异,为数据库中的每个用户执行此操作,并对结果进行平均。
解决方案可能很简单,但我无法提出有效的查询。
感谢任何帮助或建议!
答案 0 :(得分:2)
我认为您需要一个子查询来查找最早的事件,以便在事件加入中获得一行......这样的事情?
SELECT AVG(TIMESTAMPDIFF(DAY, u.created_at, e.created_at))
FROM users u
INNER JOIN events e ON u.id = e.user_id
INNER JOIN
(
SELECT user_id, MIN(created_at) minDate
FROM events
GROUP BY user_id
) m
ON m.user_id = u.user_id AND e.created_at = m.minDate
WHERE e.created_at IS NOT NULL AND u.created_at IS NOT NULL
如果不清楚,我在那里完成的是你的原始连接为每个用户提供所有事件,但是这会针对每个用户的最早事件加入,所以我们最终每个用户只有一行谁至少有一次活动。
这可以简化,因为我们不需要首先加入对抗事件,我们可以只是加入用户来反对该子查询......
SELECT AVG(TIMESTAMPDIFF(DAY, u.created_at, m.minDate))
FROM users u
INNER JOIN
(
SELECT user_id, MIN(created_at) minDate
FROM events
GROUP BY user_id
) m
ON m.user_id = u.user_id
WHERE u.created_at IS NOT NULL
答案 1 :(得分:1)
使用子查询获取第一个事件的时间(使用MIN()
而不是AVG()
)。然后取外部查询中的平均值:
SELECT AVG(x.TimeToFirstEvent)
FROM (SELECT MIN(TIMESTAMPDIFF(DAY, u.created_at, e.created_at)) as TimeToFirstEvent
FROM users u INNER JOIN
events e
ON u.id = e.user_id
WHERE e.created_at IS NOT NULL AND
u.created_at IS NOT NULL AND
e.created_at >= u.created_at -- probably not needed
GROUP BY u.id
) x;
答案 2 :(得分:0)
这是一个简短的方法:
SELECT AVG(TIMESTAMPDIFF(DAY, u.created_at,
(SELECT MIN(e.created_at) FROM events WHERE e.user_id = u.id)
))
FROM users u
请注意,AVG()将排除所有NULL值,此处不需要条件created_at IS NOT NULL
。