【问题标题】:Return the first occurrence of a user_id from a result set从结果集中返回第一次出现的 user_id
【发布时间】:2020-11-14 19:42:55
【问题描述】:

我有两张表(简化为):

+----------------+
| 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,并且只包括第一次出现(日期方面)?我怀疑这可能是不可能的。


输入/输出示例:

如果用户在 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

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

这些数据将用于构建按事件划分的唯一用户数量增长的累积图表。

【问题讨论】:

    标签: mysql sql join greatest-n-per-group min


    【解决方案1】:

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

    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
    

    【讨论】:

    • @ChuckLeButt:第一个查询不是这样吗?它为每个用户提供一行,以及第一个事件的日期。
    • @ChuckLeButt,您的意思是要统计每个事件的新用户数吗?
    • @ChuckLeButt。 . .第二个查询似乎正是您想要的。
    • 我错误地实施了第二种解决方案。它完全符合我的期望。谢谢!
    【解决方案2】:

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-09
      • 2019-12-20
      • 2012-02-02
      • 1970-01-01
      • 2016-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多