【问题标题】:MySQL - users' monthly spend in the first 6 months of initial subscription purchaseMySQL - 用户在初始订阅购买的前 6 个月的每月支出
【发布时间】:2017-09-22 16:43:53
【问题描述】:

我正在尝试为所有用户创建 6 个月内按月显示订阅价格 (AmountPerMonth) 的报告 - 其中 Month1 是用户购买第一个订阅日期(不是注册日期),Month2 等是从该日期开始的后续月份,每个帐户都不同。
The format of the table for this report

我已经设法拉出前 2 个月的表格,但不知道如何继续到第 6 个月。提前谢谢!

SELECT F1.Id, F1.Month1, F2.Month2
FROM
(SELECT Id, AmountPerMonth AS Month1, ActionDate
FROM MONTLYSPEND
GROUP BY ID
HAVING MIN(ActionDate)) AS F1,
(SELECT t1.Id R, t2.AmountPerMonth AS Month2, MIN(t2.ActionDate)
FROM MONTLYSPEND t1
INNER JOIN MONTLYSPEND t2
ON t1.Id = t2.Id
AND t1.ActionDate < t2.ActionDate
GROUP BY t1.Id) AS F2
WHERE F1.id = F2.R
;

【问题讨论】:

  • 请以文本格式添加您的表格结构。
  • 是说表中有Month3Month4....Month6等列吗?如果是这样,那么设计很可能不是normalised
  • @JenR - 我上传了一张图片; DhruvSaxena - 没错。
  • @Lya1981 这通常不是设计可伸缩表结构的最佳方式。不确定您是否最多只有 6 个月。可以想象,如果数据要超过 6 个月,表将需要有尽可能多的列来容纳它。因此,可能值得考虑按照以下几行创建一个新表:months(user_id, payment_date, amount)。这将有助于为用户添加尽可能多的月份,从而选择所需深度的记录,而无需编写过于复杂的查询。例如:this
  • @DhruvSaxena - 谢谢,是的,我已经这样做了:MONTHLYSPEND 表是我创建的视图,它正好包含这 3 个表。我尝试了不同的步骤,比如将每个用户限制为 6 个月,所以如果我按用户 ID 对它进行排序,我每个人有 6 条记录;然后我选择 Min(subscriptiondate) 作为month1 - 它很好;然后我在第二个月使用自加入,它可以工作,但它基于 date1

标签: mysql loops date


【解决方案1】:

原来有两种方法 - 存储过程,它占用太多内存,或者使用 CASE WHEN,这也可以旋转表。希望它对必须生成报告以在 x 轴上逐日或逐月显示每个用户的各种活动的人有用。我遇到的主要困难是,Month_1(首次购买的订阅)对于每个用户来说都是不同的日期。此报告可用于分析您的用户在订阅的前 6 个月内的行为。
此查询生成的报告如下所示:

+--------+----------+------------------+---------+---------+--------+
| UserId | Currency | FirstSubscrPurch | Month_1 | Month_2 | etc... |
+--------+----------+------------------+---------+---------+--------+
| 123    |   GBP    |  2010-05-27      |  34.00  |  27.00  |  0.00  |
+--------+----------+------------------+---------+---------+--------+

SELECT F6.USERID, F6.Currency, DATE_FORMAT(F6.FirstSubscrPurch, "%Y-%m-%d") AS FirstSubscrPurch, F6.MONTH_1, F6.MONTH_2,F6.MONTH_3, F6.MONTH_4, F6.MONTH_5, F6.MONTH_6, ROUND(((F6.MONTH_1+F6.MONTH_2+F6.MONTH_3+F6.MONTH_4+F6.MONTH_5+F6.MONTH_6)/6),2) AVERAGE, F6.CURRENCY

FROM (
    SELECT
        UserId, Currency, FirstSubscrPurch,
        SUM(CASE WHEN YEAR_AND_MONTH_INDEX = 0 THEN TOTAL_AMOUNT_PAID ELSE 0 END) MONTH_1,
        SUM(CASE WHEN YEAR_AND_MONTH_INDEX = 1 THEN TOTAL_AMOUNT_PAID ELSE 0 END) MONTH_2,
        SUM(CASE WHEN YEAR_AND_MONTH_INDEX = 2 THEN TOTAL_AMOUNT_PAID ELSE 0 END) MONTH_3,
        SUM(CASE WHEN YEAR_AND_MONTH_INDEX = 3 THEN TOTAL_AMOUNT_PAID ELSE 0 END) MONTH_4,
        SUM(CASE WHEN YEAR_AND_MONTH_INDEX = 4 THEN TOTAL_AMOUNT_PAID ELSE 0 END) MONTH_5,
        SUM(CASE WHEN YEAR_AND_MONTH_INDEX = 5 THEN TOTAL_AMOUNT_PAID ELSE 0 END) MONTH_6

        FROM (
            SELECT
                hp.UserId, hp.Currency, MIN(hp.Date) AS FirstSubscrPurch,
                CONCAT(YEAR(Date),'-',MONTH(Date)) AS YEAR_AND_MONTH,
                TIMESTAMPDIFF( MONTH, CONCAT(YEAR(FIRST_PAYMENT_DATE),'-',MONTH(FIRST_PAYMENT_DATE),'-1'), CONCAT(YEAR(Date),'-',MONTH(Date),'-1')) AS YEAR_AND_MONTH_INDEX, -- generates string in format YYYY-M-D
                MIN(Date) FIRST_PAYMENT_OF_MONTH, 
                MAX(Date) LAST_PAYMENT_OF_MONTH, 
                COUNT(*) NUM_PAYMENTS,
                SUM(hp.Amount) TOTAL_AMOUNT_PAID, 
                SUM(hp.Credits) Credits
                FROM payments hp
                JOIN (
                    SELECT UserId, MIN(Date) FIRST_PAYMENT_DATE, ADDDATE(MIN(Date), INTERVAL 6 MONTH) SIX_MONTHS_AFTER_FIRST_PAYMENT
                    FROM payments hp 
                    GROUP BY UserId
                    ) USER_MIN_ID ON USER_MIN_ID.UserId = hp.UserId 
                    AND hp.Date BETWEEN FIRST_PAYMENT_DATE AND CONCAT(YEAR(SIX_MONTHS_AFTER_FIRST_PAYMENT),'-',MONTH(SIX_MONTHS_AFTER_FIRST_PAYMENT),'-1')
                    GROUP BY UserId, Currency, YEAR_AND_MONTH
                ORDER BY hp.UserId, hp.Date
            ) F
        GROUP BY UserId, Currency
ORDER BY UserId DESC) F6;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 2012-01-03
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多