MYSQL内部联接的平均最小值

MYSQL内部联接的平均最小值,mysql,sql,Mysql,Sql,鉴于有两个表格: 事件 使用者 允许每个用户有一个或多个事件 每个事件只能由一个用户拥有 我将下面的查询放在一起,以平均在事件和用户的时间戳处创建的相应_之间的差异 SELECT ( SELECT AVG(TIMESTAMPDIFF(DAY, users.created_at, events.created_at)) FROM users INNER JOIN events ON users.id = events.user_id WHERE eve

鉴于有两个表格:

  • 事件
  • 使用者
允许每个
用户
有一个或多个事件

每个
事件
只能由一个用户拥有

我将下面的查询放在一起,以平均在事件和用户的时间戳处创建的相应_之间的差异

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."
但是,如果event.created_at的时间戳最低,那么如何只包括第一个重叠?我相信目前,代码会将每个时间戳和创建的时间戳之间的差异取出来,并将其平均。我试图为每个用户获取他/她的第一个创建事件之间的差异,为数据库中的每个用户执行此操作,并平均结果

解决方案可能相当简单,但我无法提出有效的查询


感谢您的帮助和建议

使用子查询获取第一个事件的时间(使用
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;

我认为您需要一个子查询来查找最早的事件,以便在事件联接中获得一行…类似这样的内容

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
这里有一条捷径:

SELECT AVG(TIMESTAMPDIFF(DAY, u.created_at, 
    (SELECT MIN(e.created_at) FROM events WHERE e.user_id = u.id)
))
FROM users u

请注意,AVG()将排除所有空值,此处不需要创建的条件
不为空。

请参阅Oops,对此表示抱歉。正在添加有用的信息。为什么需要加入事件?你可以使用
m.minDate
而不是
e.created\u at
。非常酷——两个答案似乎产生相同的结果。感谢您提供了更容易理解的示例!