2011-05-04 20 views
0

我有各种套餐的服务,可以每月,每季度,每半年和每年购买一次。计算各种条件下的经常性支付的未来收入预测

每个软件包都有一个due_on日期,当有人续约时我会增加这个日期。

通过查看本月哪些人有due_on日期,可以轻松计算出本月可以粗略估计的收入。

我遇到麻烦的地方是计算明年我每月可以得到多少收入。我不能以此为基础,因为有些人会在明年支付12次,还有6支等。

这样做的最佳方法是什么? 注意:为此,我忽略了摩擦。 我正在使用PHP和MySQL,但我在寻求理论,所以不应该太重要。

回答

1

让我们来计算未来12个月的月收入。

我可以看到两个基本的方法来做到这一点:

  1. 每个未来12个月的创建桶的阵列(或哈希)。然后,遍历每个活动订阅,并为每个订阅添加预期的收入,并将其从每个适当的存储桶中添加。例如,如果条款是每月,请将该付款添加到每个存储分区;如果该期限是季度,则将该付款添加到当前的due_date月份存储桶以及之后3个月,6个月和9个月的存储桶;等等。编码相当简单,但有足够的客户生成报告可能需要一些时间。

  2. 在有(monthamount)列MySQL数据库创建一个临时表,一系列的INSERT语句填充它(有一堆,我会得到他们在一分钟),然后在该表上做一个报告。

    这有点不寻常,所以我要详细说明一下。我对你的SQL表格结构做了一些假设,但我试图尽可能使它保持通用。

    所以首先你需要临时表,我们将根据当前due_on日期,每一个月的收入开始往里面:

    CREATE TEMPORARY TABLE FutureRevenueReport 
    SELECT 
        CONCAT(YEAR(s.due_on), '-', MONTH(s.due_on)) as revenue_month, 
        s.due_amount as revenue_amount 
    FROM subscriptions s WHERE s.active = 'True'; 
    

    现在在同一个MySQL的会议上,执行这一系列插入语句来填补未来的收入:

    INSERT INTO FutureRevenueReport(revenue_month, revenue_amount) 
    SELECT CONCAT(YEAR(s.due_on + INTERVAL 1 MONTH), '-', 
           MONTH(s.due_on + INTERVAL 1 MONTH)), s.due_amount 
    FROM subscriptions s WHERE s.active = 'True' AND s.term = 'MONTHLY'; 
    
    INSERT INTO FutureRevenueReport(revenue_month, revenue_amount) 
    SELECT CONCAT(YEAR(s.due_on + INTERVAL 2 MONTH), '-', 
           MONTH(s.due_on + INTERVAL 2 MONTH)), s.due_amount 
    FROM subscriptions s WHERE s.active = 'True' AND s.term = 'MONTHLY'; 
    
    INSERT INTO FutureRevenueReport(revenue_month, revenue_amount) 
    SELECT CONCAT(YEAR(s.due_on + INTERVAL 3 MONTH), '-', 
           MONTH(s.due_on + INTERVAL 3 MONTH)), s.due_amount 
    FROM subscriptions s WHERE s.active = 'True' AND s.term = 'MONTHLY'; 
    -- etc, up to + INTERVAL 11 MONTH 
    
    -- Now the quarterly: 
    INSERT INTO FutureRevenueReport(revenue_month, revenue_amount) 
    SELECT CONCAT(YEAR(s.due_on + INTERVAL 3 MONTH), '-', 
           MONTH(s.due_on + INTERVAL 3 MONTH)), s.due_amount 
    FROM subscriptions s WHERE s.active = 'True' AND s.term = 'QUARTERLY'; 
    
    INSERT INTO FutureRevenueReport(revenue_month, revenue_amount) 
    SELECT CONCAT(YEAR(s.due_on + INTERVAL 6 MONTH), '-', 
           MONTH(s.due_on + INTERVAL 6 MONTH)), s.due_amount 
    FROM subscriptions s WHERE s.active = 'True' AND s.term = 'QUARTERLY'; 
    -- And the same for 9 months 
    -- Then do the same thing for SEMI-ANNUALLY and + INTERVAL 6 MONTH 
    
    -- And now the report: 
    SELECT revenue_month, sum(revenue_amount) as revenue from FutureRevenueReport 
    GROUP BY revenue_month; 
    
+0

真棒!谢谢!我想到了第一个,但似乎需要很长时间才能运行。我们实施了第二个,它效果很好!感谢您的深入响应! – 2011-05-06 19:57:45