简体   繁体   English

用户事件表中一天的MYSQL'SELECT'和COUNT个“活动”用户

[英]MYSQL 'SELECT' and COUNT “active” user for day in user event table

+----+--------------+------------+--------+
| id | user    | date(data) | type        |
+----+--------------+------------+--------+
|  3 | 5458848 | 2013-12-19 | SUBSCRIBE   |
|  4 | 5458848 | 2013-12-19 | UNSUBSCRIBE |
|  5 | 5458848 | 2013-12-20 | SUBSCRIBE   |
|  7 | 5458848 | 2013-12-20 | UNSUBSCRIBE |
|  8 | 7883870 | 2013-12-20 | SUBSCRIBE   |
|  9 | 7883870 | 2013-12-23 | UNSUBSCRIBE |
| 10 | 7883870 | 2013-12-24 | SUBSCRIBE   |
| 11 | 7883870 | 2013-12-24 | UNSUBSCRIBE |
| 12 | 7883870 | 2013-12-24 | SUBSCRIBE   |
+----+---------+------------+-------------+                                                 

Hello, I need to know how make query in mysql for watch how many users have active and not-active daily, 您好,我需要了解如何在mysql中进行查询,以观察每天有多少用户处于活动状态和非活动状态,

example: if one user is SUBSCRIBE and UNSUBSCRIBE in the same day, it mean that for that day, I have a user not-active 例如:如果一个用户在同一天是SUBSCRIBE和UNSUBSCRIBE,则表示在该天我有一个用户未激活

+------------+-------------+-------------+
| date(data) | active      | inactive    |
+------------+-------------+-------------+
| 2013-12-19 | 0           | 1           |
| 2013-12-20 | 1           | 1           |
| 2013-12-23 | 0           | 2           |
| 2013-12-24 | 1           | 1           |
+------------+-------------+-------------+

Try this... 尝试这个...

SELECT SUM(CASE WHEN type='SUBSCRIBE' THEN 1 ELSE 0 END) as active,
       SUM(CASE WHEN type='UNSUBSCRIBE' THEN 1 ELSE 0 END) as inactive
WHERE (date>='2013-12-19' and date<='2013-12-24');

You need the difference between the cumulative number of subscribes and unsubscribes on each date in order to calculate whether someone has subscribed or not. 您需要每个日期的累计订阅数和取消订阅数之间的差额,以便计算某人是否已订阅。 For example, the last user 7883870 has a state of "subscribe" after three events on the same day. 例如,在同一天的三个事件之后,最后一个用户7883870的状态为“订阅”。

One way to do this is with correlated subqueries: 一种方法是使用相关子查询:

select t.user, t.date,
       (select sum(type = 'SUBSCRIBE') - sum(type = 'UNSUBSCRIBE')
        from table t2
        where t2.user = t.user and
              t2.date <= t.date
       ) netsubs
from table t
group by t.user, t.date;

WIth this information, we can then determine the state someone is in on a given date. 利用这些信息,我们可以确定某人在给定日期所处的状态。

select date, 
       sum(case when netsubs > 0 then 1 else 0 end) as active,
       sum(case when netsubs = 0 then 1 else 0 end) as inactive
from (select t.user, t.date,
             (select sum(type = 'SUBSCRIBE') - sum(type = 'UNSUBSCRIBE')
              from table t2
              where t2.user = t.user and
                    t2.date <= t.date
             ) netsubs
      from table t
      group by t.user, t.date
     ) t
group by t.date;

EDIT: 编辑:

I misunderstood the question. 我误解了这个问题。 On any given day, you want the number of users that are active or have unsubscribed up to that point. 在任何给定的日期,您都希望在此之前处于活动状态或尚未预订的用户数量。

select date, numacive, numusers - numactive as numinactive
from (select date,
             (select count(distinct user)
              from table t2
              where t2.date <= t.date
             ) as numusers,
             (select sum(type = 'SUBSCRIBE') - sum(type = 'UNSUBSCRIBE')
              from table t2
              where t2.date <= t.date
             ) as numactive
      from (select distinct date
            from table t
           ) t
     ) t;
set @ac:=null;
DROP TABLE IF EXISTS ___active_nums;

CREATE TABLE ___active_nums(
  event_id integer,
  event_user_id integer,
  event_date  Date,
  number_of_active_users integer,
  INDEX USING BTREE (event_date)
)
ENGINE=MEMORY 
;

INSERT INTO ___active_nums

SELECT

  events.id,
  events.user,
  events.date,
  ifnull( @ac:= ( @ac + if( type='SUBSCRIBE', 1, -1) ), @ac:=if( type='SUBSCRIBE', 1, -1) ) AS active_num

FROM 
(
  SELECT * FROM events ORDER BY id
)
AS events
;

SELECT

event_date as date,
number_of_active_users,

( SELECT count(DISTINCT event_user_id) FROM ___active_nums WHERE ___active_nums.event_date <= outer_active_nums.event_date )
- number_of_active_users
as number_of_inactive_users

FROM ___active_nums  AS outer_active_nums

WHERE event_id IN ( SELECT max(event_id) FROM ___active_nums GROUP BY event_date );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM