如何获取下一个日期/如何获得每次入住的时长

时间:2016-03-14 11:10:58

标签: mysql

我需要计算一个月内订阅的人数,例如一月,当他们离开时:它看起来像:所以看起来像:

e.g。看着1月份有50位订阅者

MONTH(t2.leavedate) || COUNT(t1.subscribed1) 
January             || 10
February            || 15
March               || 3

因此,1月份队列中有50人(即1月份订阅了50人),剩下28人 - 当28人离开时,我希望我的查询输出。

这是我所拥有的表格(tableX),它显示了每个事件和user_id:

我有这个包含事件的表

id||user_id||event_name||date of event
4 ||   10  || subscribe|| 2016-01-25
5 ||   11  || subscribe|| 2016-01-30
6 ||   12  || subscribe|| 2016-01-30
7 ||   13  || leave    || 2016-02-02
8 ||   14  || subscribe|| 2016-02-03

如果我只过滤一个用户,user_id = 10(user10) - 其中user10是重新加入的示例(多个'订阅'事件,多个'离开',表格想:

id ||user_id||event_name||date of event
 4 ||   10  || subscribe|| 2016-01-25
20 ||   10  || leave    || 2016-01-30
32 ||   10  || subscribe|| 2016-01-30
45 ||   10  || leave    || 2016-02-02
60 ||   10  || subscribe|| 2016-02-03
70 ||   10  || leave    || 2016-03-10

这是我必须计算一个月内订阅者数量的查询:

SELECT MONTHNAME(t1.joindate), COUNT(t1.subscribed1)
FROM tableX
JOIN
(SELECT tableX.user_id AS subscribed1, tableX.date_of_event AS joindate
    FROM 
        tableX
    WHERE tableX.event_name = "subscribed"
    GROUP BY tableX.id
    )t1
    ON t1.subscribed1 = tableX.user_id
WHERE event_name = 'subscribed'
GROUP BY MONTHNAME(t1.joindate)
ORDER BY t1.joindate ASC;

我遇到的问题是,如果我正在查看例如1月 - 重新加入,例如user10,在计算订阅者数量时会显示为2(COUNT(tableX.ids)) - 但是当我COUNT(t1.subscribed1)在1月份离开两次时会出现3次,而在3月份则会出现3次(总共一次,它将显示user10,作为1月份队列的一部分,离开三次,再次,user10将显示在我的订阅者计数2月队列 - 但显示用户离开3次。当我想要的2月队列,将将user10计为2月一次,并在3月离开一次

我想按顺序计算这些事件,例如2月的下一个休假日期是3月。我尝试过使用MAX-MIN和t2.leavedate> = t1.joindate等函数

这是我迄今为止所尝试过的,但它似乎并没有反映出正确的数字:

SELECT MONTHNAME(t2.leavedate), COUNT(t2.cancelled2)

    FROM tableX

JOIN 

(SELECT MONTHNAME(tableX.date_of_event), tableX.user_id AS subscribed1, tableX.date_of_event AS joindate
    FROM 
        user_account_events
    WHERE tableX.event_name = "subscribed"

    GROUP BY tableX.id
    )t1

    ON t1.subscribed1 = tableX.user_id

JOIN 

    (SELECT tableX.user_id AS cancelled2, tableX.date_of_event AS leavedate
        FROM tableX
    WHERE
        tableX.event_name = "leave"
    GROUP BY tableX.user_id
    )t2
    ON t2.cancelled2 = t1.subscribed1


WHERE tableX.date_of_event = 'leave'
AND t1.joindate BETWEEN '2016-01-01 00:00:00' AND '2016-02-01 00:00:00'
*AND t2.leavedate >= t1.joindate*

GROUP BY MONTH(t2.leavedate)
ORDER BY t2.leavedate;

1月份队列的预期输出即:(t1.joindate BETWEEN' 2016-01-01 00:00:00' AND' 2016-02-01 00:00:00' )

MONTH(t2.leavedate) || COUNT(t1.subscribed1) 
January             || 10
February            || 15

所以,最终,我想创建一个如下所示的表:

                    Nov || Dec || Jan || Feb ||
No. of Subscribers|| 10 || 15  || 50  || 25  ||

Leave Month
              Nov || 1  ||     ||
              Dec || 3  || 2   ||
              Jan || 1  || 5   || 10 || 
              Feb || 2  || 3   || 15 || 6 ||
               ____________________________
 Total 'leaves'   || 7 || 10  || 25  || 6 ||

即。 11月份订阅的10人中有7人离开了。 (11月份队列中只有3名活跃用户)

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

此查询可让您知道某个日期是否存在“user_id”

SELECT user_id, SUM(IF(event_name="suscribe", 1, -1)) AS is_suscribed FROM `tableX` WHERE date_of_event < '2016-01-25' GROUP BY user_id

如果你想让嫌疑人在一个月内计算:

SELECT COUNT(*) FROM (SELECT user_id, SUM(IF(event_name="suscribe", 1, -1)) AS is_suscribed FROM `tableX` WHERE MONTH(date_of_event)=1 AND YEAR(date_of_event)=2016 GROUP BY user_id) AS real_suscription WHERE is_suscribed > 0

或者,如果您希望一个月内取消用户计算:

SELECT COUNT(*) FROM (SELECT user_id, SUM(IF(event_name="suscribe", 1, -1)) AS is_suscribed FROM `tableX` WHERE MONTH(date_of_event)=1 AND YEAR(date_of_event)=2016 GROUP BY user_id) AS real_suscription WHERE is_suscribed < 0

答案 1 :(得分:0)

我认为这可能对你有好处

SELECT 
  DATE_FORMAT(next_leave_date, '%Y-%m'), 
  count(user_id) 
FROM (
  SELECT 
    tableX.user_id AS user_id, 
    MAX(tableX.date_of_event) AS next_leave_date
  FROM 
    tableX 
    JOIN ( -- get target user lists
      SELECT 
        DISTINCT user_id
      FROM 
        tableX
      WHERE date_of_event >= '2015-01-01'
        and date_of_event <  '2015-02-01'
    ) AS target_users ON tableX.user_id = target_users.user_id
    LEFT JOIN (
      SELECT 
        user_id, min(date_of_event)
      FROM
        tableX
      WHERE date_of_event >= '2015-02-01'
        AND event_name = 'subscribed'
        AND user_id IN (
          SELECT 
            DISTINCT user_id
          FROM 
            tableX
          WHERE date_of_event >= '2015-01-01'
            and date_of_event <  '2015-02-01'
        )
      GROUP BY user_id
    ) AS taget_users_with_next_sub_date ON tableX.user_id = taget_users_with_next_sub_date.user_id
  WHERE event_name = 'leave'
  GROUP BY tableX.user_id
) AS users_and_their_date_of_leave
GROUP BY DATE_FORMAT(next_leave_date, '%Y-%m');

这是一个相对复杂的SQL查询。我放在这里只能帮助您分析一个月内订阅的用户。因此,如果您想进行连贯分析,则需要多次运行,每次运行不同的月份。

我建议你在商店程序中执行此操作并将月份作为参数,这可以为您节省一些时间。