我有一个跟踪花钱的应用程序。我有一个功能,可以在本月和上个月花掉所有的钱。它是一个或另一个,而不是两者。它基于以下名为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();
答案 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)
如果选择......会得到什么结果?
...对于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天');