2013-11-25 113 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