Return 结果集中第一次出现 user_id

Return the first occurrence of a user_id from a result set

我有两个表(简化为):

+----------------+
| attendances    |
+-----+----------+
| int | user_id  |
+-----+----------+
| int | event_id |
+-----+----------+

+-------------------------+
| events                  |
+------+------------------+
| int  | id               |
+------+------------------+
| date | performance_date |
+------+------------------+

以及一个简单的查询:

SELECT count(DISTINCT user_id), events.performance_date
FROM attendances
INNER JOIN events
    ON event_id = events.id
GROUP BY performance_date 

我只想计算每个 user_id 一次,但上面的查询只删除每个 performance_date 中的重复项(允许它们在多个日期重复)。

是否有一个查询可以从整个结果集中删除重复的 user_ids,并且只包括第一次出现的(日期明智的)?我怀疑这不可能。


Input/output 例子:

如果用户在 2010 年 10 月 10 日和 2010 年 10 月 11 日再次参加活动,则结果将是:

1, 2010-10-10

不是:

1, 2010-10-10
1, 2010-10-11

或:

2, 2010-10-10

如果在上面添加了另一个用户,并且他们分别在 2010 年 10 月 10 日和 2010 年 10 月 12 日参加,那么结果将是:

2, 2010-10-10
1, 2020-10-12

正如我所说,这可能是不可能的。实际输出并不严格——只要可以以某种方式得出参加特定表演的人数的唯一数量即可。

数据将用于构建独立用户数量按事件增长的累积图。

如果您想要每个用户的最早日期,您可以使用聚合:

select u.id user_id, min(e.date) first_event_date
from users u
inner join events e on u.event_id = e.id
group by u.id

实际上,您可能正在寻找直方图,即每个最早事件日期的用户数。您可以通过添加另一个聚合级别来完成此操作:

select first_event_date, count(*) no_users
from (
    select min(e.date) first_event_date
    from users u
    inner join events e on u.event_id = e.id
    group by u.id
) t
group by first_event_date

如果您想统计每个事件的所有新用户,您可以使用以下查询:

SELECT Count(u.user_id), 
       e.performance_date 
FROM   attendances u 
       INNER JOIN `events` e 
               ON u.event_id = e.id 
WHERE  NOT EXISTS(SELECT u1.user_id 
                  FROM   attendances u1 
                         INNER JOIN `events` e1 
                                 ON u1.event_id = e1.id 
                  WHERE  u1.user_id = u.user_id 
                         AND e1.performance_date < e.performance_date) 
GROUP  BY performance_date 
ORDER  BY performance_date

我用下面的设置测试了它:

CREATE TABLE attendances 
  ( 
     user_id  INT, 
     event_id INT 
  ); 

CREATE TABLE `events` 
  ( 
     id               INT, 
     performance_date DATE 
  ); 

INSERT INTO attendances 
            (user_id, 
             event_id) 
VALUES      ( 1, 1),
            ( 1, 2),
            ( 2, 1),
            ( 2, 2),
            ( 3, 1),
            ( 4, 2);

INSERT INTO `events` 
            (id, 
             performance_date) 
VALUES      ( 1, '2020-07-24'), 
            ( 2, '2020-07-25'); 

然后结果是

3  2020-07-24
1  2020-07-25