在SQLite中使用datetime来获取本月和上个月的值

时间:2016-08-23 16:31:35

标签: android sql sqlite android-sqlite

我有一个跟踪花钱的应用程序。我有一个功能,可以在本月和上个月花掉所有的钱。它是一个或另一个,而不是两者。它基于以下名为lastMonth的参数。

每笔交易金额都以交易日期进入我的表格。我使用SQL查询来总计它。像这样:

 if (!lastMonth) {

            query += "WHERE ("
                        + "CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 >= CAST(strftime('%s', date('now','start of month')) AS INT)  "
                        + "AND "
                        + " CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 < CAST(strftime('%s', date('now','start of month','+1 month')) AS INT) ); ";

            } else {

                query += "WHERE ("
                        + "CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 BETWEEN CAST(strftime('%s', datetime('now','start of month', '-1 month')) AS INT)  "
                        + "AND CAST(strftime('%s', date('now','start of month')) AS INT) ); ";
            }

主要是有效。但它似乎在本月的最后一天遇到麻烦。例如,这个问题将在8月发布。因此,应用程序仪表板目前显示了8月和7月所花的所有资金。

问题:7月31日的所有交易(或上个月最后一天的交易)都是8月份的总交易量。 7月份的总数不包括7月31日。

修改

我想知道SQL是否正确,但我将数据库中的日期设置错误。这是代码:

                Calendar cal = Calendar.getInstance();
                timestamp = cal.getTimeInMillis();

4 个答案:

答案 0 :(得分:2)

使用BETWEEN会使你的LastMonth语句包含超过1个月。 BETWEEN与&gt; = AND&lt; =相同。所以当你说这个问题时。

COLUMN_GAS_UNIX_TIMESTAMP >= [Start of Last Month]
AND COLUMN_GAS_UNIX_TIMESTAMP <= [Start of This Month] 

是否返回超过1个月的日期。本月的所有上个月和第一天。

您当前月份查询的另一个想法是,您能否认为COLUMN_GAS_UNIX_TIMESTAMP永远不会超过NOW?如果是这样,您不需要做任何事情,只需检查COLUMN_GAS_UNIX_TIMESTAMP is >= Start of Month.

您可以尝试以下内容:

 if (!lastMonth) {

            query += "WHERE ("
                        + "CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 >= CAST(strftime('%s', date('now','start of month')) AS INT)  ";
            } else {

                query += "WHERE ("
                            + "CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 >= CAST(strftime('%s', datetime('now','start of month', '-1 month')) AS INT)  "
                            + "AND "
                            + " CAST(" + MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP + " AS INT)/1000 < CAST(strftime('%s', date('now','start of month')) AS INT) ); ";
            }

答案 1 :(得分:1)

如果选择......会得到什么结果?

  • MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP
  • CAST(“+ MySQLiteHelper.COLUMN_GAS_UNIX_TIMESTAMP +”AS INT)/ 1000
  • CAST(strftime('%s',日期('现在','月初'))AS INT)
  • CAST(strftime('%s',日期('现在','月初','+ 1个月'))AS INT)
  • CAST(strftime('%s',日期时间('现在','月初','1个月'))AS INT)

...对于7月30日和31日以及8月1日和2日的交易?

转换为INT然后除以1000将通常截断您的结果,因为除法将作用于整数(例如,整数14680除以1000将给出答案14)。这是你想要的行为吗?如果将CAST(strftime)部分乘以1000而不是将TIMESTAMP除以1000,它会得到相同的结果吗?

为了帮助您调试一致性,您可能还需要考虑在if / else的两侧使用相同的语法(例如,对两个WHERE子句使用BETWEEN),并且还要在使用date()和datetime()之间切换在您的查询中,这也可能会产生计划外的结果。

答案 2 :(得分:1)

计算每月的最后一天并不是日期/日期时间值的唯一问题。

如果您在中午发布的月份的最后一天有值。如果您仅与没有日期时间的日期进行比较,则不会计算在内。

你应该做这样的计算,其中&gt; = '01 / 01/2015 00:00:00,其中date&lt; 02/01/2015 00:00:00这样,所有2015年1月31日的记录都会被计算在内,无论他们什么时候加盖时间戳。或者您可以删除月份,日期和年份,忽略时间'20150101'和'20150131'作为比较中的字符串。

答案 3 :(得分:0)

计算当月的最后一天。 选择日期('现在','月初','+ 1个月',' - 1天');