2013-11-25 69 views
0

月我有一個SQLite表如下所謂的平衡歷史:計算平均爲SQLite中

表餘額歷史

Date     Amount 
2013-11-01 16:26:52 1000 
2013-11-15 13:20:52 2000 
2013-11-27 12:26:55 3000 

我想計算的平均月供。

**

  • 預期的輸出將是1666.67

** 這將是(1000 *14天+ 2000 *12天+ 3000 * 4天)/30天 =(14000 + 24000 + 12000)/ 30 = 1666.67

我該如何在SQlite中實現這一目標?任何幫助將不勝感激。

謝謝

+0

真的有必要使用日期格式不是的[支持的日期格式]一個(http://www.sqlite.org/datatype3。 HTML#日期時間)? –

+0

謝謝,CL我只是把日期作爲例子。我在實際表格中使用了正確的日期格式。但是,我怎麼能得到提到的邏輯來計算在sqlite中的平均值? – Drunkenelf

+0

您的表格是否僅包含一個月的數據? –

回答

0

首先,我們必須計算每個間隔的開始和結束。

簡單查詢(SELECT Date AS "From", Amount FROM BalanceHistory WHERE Date GLOB '2013-11*')獲取月份中每個區間的開始。 (GLOB是大小寫敏感的,因此允許使用普通索引; LIKE可能需要一個特殊大小寫不敏感指數)

如果當月的第一天沒有記錄,在UNION ALL後的部分添加上個月的最後一個記錄,並將當天更改爲第1天。

COALESCE計算間隔的結束。 子查詢從表中獲取下一個日期(如果當前月份中有一個)。 如果沒有這樣的記錄,它需要下個月的第一天:

SELECT date("From") AS "From", 
     COALESCE((SELECT date(MIN(Date)) 
       FROM BalanceHistory 
       WHERE Date > "From" 
        AND Date GLOB '2013-11*'), 
       date('2013-11-01', '+1 month') 
       ) AS "To", 
     "Amount" 
FROM (SELECT Date AS "From", 
      Amount 
     FROM BalanceHistory 
     WHERE Date GLOB '2013-11*' 
     UNION ALL 
     SELECT * 
     FROM (SELECT date(Date, '+1 month', 'start of month'), 
        Amount 
      FROM BalanceHistory 
      WHERE Date < '2013-11' 
       AND NOT EXISTS (SELECT 1 
           FROM BalanceHistory 
           WHERE Date GLOB '2013-11-01*') 
      ORDER BY Date DESC 
      LIMIT 1) 
    ); 
From  To   Amount  
---------- ---------- ------ 
2013-11-01 2013-11-15 1000 
2013-11-15 2013-11-27 2000 
2013-11-27 2013-12-01 3000 

我們然後可以在另一個查詢來計算天數把這個包,並把它們加起來。 的strftime計算當月,即天數的最後一天:

SELECT SUM((julianday("To") - julianday("From")) * Amount)/
     strftime('%d', '2013-11-01', '+1 month', '-1 day') AS MonthAvg 
FROM (SELECT date("From") AS "From", 
      COALESCE((SELECT date(MIN(Date)) 
         FROM BalanceHistory 
         WHERE Date > "From" 
         AND Date GLOB '2013-11*'), 
         date('2013-11-01', '+1 month') 
        ) AS "To", 
      "Amount" 
     FROM (SELECT Date AS "From", 
        Amount 
      FROM BalanceHistory 
      WHERE Date GLOB '2013-11*' 
      UNION ALL 
      SELECT * 
      FROM (SELECT date(Date, '+1 month', 'start of month'), 
         Amount 
        FROM BalanceHistory 
        WHERE Date < '2013-11' 
        AND NOT EXISTS (SELECT 1 
            FROM BalanceHistory 
            WHERE Date GLOB '2013-11-01*') 
        ORDER BY Date DESC 
        LIMIT 1) 
      ) 
    ) 

雖然我們在這,我們就可以在另一個查詢包裹它來取代所有這些2013-11字符串與月從表中讀取。 這允許計算這每個月:

SELECT Month, 
     (SELECT SUM((julianday("To") - julianday("From")) * Amount)/
       strftime('%d', Month || '-01', '+1 month', '-1 day') 
     FROM (SELECT date("From") AS "From", 
        COALESCE((SELECT date(MIN(Date)) 
           FROM BalanceHistory 
           WHERE Date > "From" 
           AND Date GLOB Month || '*'), 
           date(Month || '-01', '+1 month') 
          ) AS "To", 
        "Amount" 
       FROM (SELECT Date AS "From", 
          Amount 
        FROM BalanceHistory 
        WHERE Date GLOB Month || '*' 
        UNION ALL 
        SELECT * 
        FROM (SELECT date(Date, '+1 month', 'start of month'), 
           Amount 
          FROM BalanceHistory 
          WHERE Date < Month 
          AND NOT EXISTS (SELECT 1 
              FROM BalanceHistory 
              WHERE Date GLOB Month || '-01*') 
          ORDER BY Date DESC 
          LIMIT 1) 
        ) 
      ) 
     ) AS MonthAvg 
FROM (SELECT DISTINCT strftime('%Y-%m', Date) AS Month 
     FROM BalanceHistory) 
ORDER BY 1 
+0

謝謝你,快速回復CL。今天會經歷這個,如果我有任何疑問,我會回覆你。否則,肯定會將此標記爲答案。再次感謝您的時間。 – Drunkenelf