-1

我有一个超过 120 万会员的会员名单。人们通常订阅、取消订阅和重新订阅该列表。通常,我发现自己需要知道在特定时间点订阅了哪些用户。我有一个名为 subscription_history 的表,其结构如下:

-----------------------------------------------------------------------
| id           | native key                                           |
-----------------------------------------------------------------------
| user_id      | foreign key that joins the user table                |
-----------------------------------------------------------------------
| change_code  |  1 or 2 for subscriptions, 4-7 for unsubscriptions   |
-----------------------------------------------------------------------
| created_at   | date-time stamp when the change was made             |
-----------------------------------------------------------------------

现在,如果我想知道过去某个特定日期(本例中为 2012 年 3 月 31 日)的订阅者,我运行以下查询:

SELECT user_id
FROM
  (SELECT 
    user_id
  , MAX(created_at) AS last_change_date
  , change_code
  FROM subscriptionhistory
  WHERE DATE(created_at) <= '2012-03-31'
  GROUP BY user_id
  ) AS last
WHERE change_code IN (1,2)

这会查找每个用户在目标日期之前或目标日期之前的最后一次订阅操作,然后如果该操作是订阅,则返回用户。然后,我们使用该用户列表来运行各种其他查询,例如平均生命周期销售额。该系统运行良好,但一次只能用于一个日期。如果我想知道一年中每个月的平均订阅者的终身销售额,我必须运行这个查询 12 次,每次手动增加WHERE语句中的日期。

现在我想创建一个可以在多个日期使用的版本......这样它就可以给我所有在一月份订阅的用户,然后是二月份等等,我可以为订阅者计算平均终身销售额在每个月。我不能仅仅GROUP BY为此做一个,因为在 3 月份订阅的人可能在 4 月份退订并在 6 月份重新订阅。我想我可以进行 12UNION次查询……但希望有更优雅的东西!

一些限制参数:我对数据库只有只读权限;我无法更改表结构或制作临时表。我必须只在 MySQL 中执行此操作——因为我们的 CRM 工作方式,我不能使用 Python 或 PHP 来操作结果。任何帮助将不胜感激!如果我解释得不好,请告诉我。谢谢!

4

1 回答 1

0
SELECT user_id, group_concat(date_format(created_at, '%Y-%m')) as ActiveMonth from 
(SELECT user_id, created_at, change_code from Subscriptions WHERE
 change_code in (1,2) order by 1,2,3) b 
group by user_id
order by user_id, ActiveMonth desc

您可以取出 group_concat 和 group by,它应该为每个 user_id 提供一行和活动月份。

我创建了一个 SQLFiddle 并将表名更改为订阅以便于使用。

http://sqlfiddle.com/#!2/6b2f2/14

于 2013-09-18T20:16:02.017 回答