如何实现连接以获取第一个 table 列中指定日期之前第二个 table 中所有记录的计数

How to implement a join for getting count of all records in 2nd table prior to a date that is specified in a column of 1st table

我有两个table我们称它们为用户、事件

users: [user_id, activity_date]
       [123,     4-28-2020    ]
       [456,     4-27-2020    ]

events: [user_id, event_date]
       [123,     5-28-2020    ]
       [456,     4-27-2020    ]
       [456,     4-25-2020    ]
       [456,     4-30-2020    ]
       [456,     1-30-2020    ]
       [123,     1-28-2020    ]

我想要一个汇总 table,它为每个用户显示事件 table 中存储在 users.activity_date 中的值之前的事件计数。

所以上面的例子会产生:

[user_id, total]
[123,       1  ]
[456,       3  ]    

我有点困惑如何写这个,我知道我需要加入 user_id,然后根据 activity_date 在事件中过滤 activity_date 的值指定的值...有人知道怎么做吗?

一个简单的方法是关联子查询:

select u.*,
       (select count(*)
        from events
        where e.user_id = u.user_id and e.event_date < u.activity_date
       ) as events_before
from users u;

另一种方法使用 window 函数和累加和:

select u.*, e.cnt
from users u left join
     (select e.*,
             lead(event_date) over (partition by user_id order by event_date) as next_event_date,
             row_number() over (partition by user_id order by event_date) as cnt
      from events e
     ) e
     on u.user_id = e.user_id and
        u.activity_date >= e.event_date and
        (u.activity_date < e.next_event_date or e.next_event_date is null);

这不是完全一样的逻辑。它计算在同一时间发生的事件(因此它不是“严格之前”。此外,如果事件恰好在同一时间发生,事情就会变得棘手。

这两个都可以修复,但是它们使逻辑复杂化,所以我坚持这个。