2011-05-04 56 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