我想在日历下方显示每个/选定月份的总费用。
我将费用总额存储在这样的数据库中:
public double getTotal(String email, int month) {
SQLiteDatabase db = this.getWritableDatabase();
int total;
Cursor cursor = db.rawQuery("SELECT SUM( Amount ) as Amount FROM " + "UserExpenses" + " WHERE " + KEY_MONTH + "=" + month + "",null);
if (cursor.moveToFirst()) {
total = cursor.getInt(cursor.getColumnIndex("Amount"));// get final total
return total;
}
else
total = -1;
cursor.close();
return 0;
}
即使滚动月份,我也只能得到所选月份的总费用
Calendar c = Calendar.getInstance();
int month = c.get(Calendar.MONTH);
totalExpense = dataBaseHelper.getTotal(email, month);
expense = findViewById(R.id.expense);
expense.setText(String.valueOf(totalExpense));
答案 0 :(得分:2)
您可以对使用GROUP BY子句分组的数据运行使用sum(x)函数的查询。
sum(x)基金是一个聚合函数,返回添加x列的结果,该列将作用于GROUP BY子句确定的一组行。
GROUP BY子句应根据年份和月份分组。
因此,SQL将遵循
SELECT sum(your_amount_column), your_year_column, your_month_column FROM your_table GROUP BY your_email_column,your_year_column, your_month_column;
要根据日历下方每个<选定的月份/选定的月份进行选择。。那么WHERE子句也应允许选择。通过将日期存储为单独的实体(例如,年月日是单独的列),选择起来很复杂。因此要选择一个日期范围(假设存储了jan 1 ,存储了2月2日,等等),那么当20192(2019年2月)大于201912(排序时,如果简单地串联起来),就会出现问题。需要一些操作,例如将年份乘以100再加上。
选择日期范围时,可以使用使用BETWEEN子句的WHERE子句:-
WHERE (year * 100) + month BETWEEN ((start_year * 100) + start_month) AND ((end_year * 100) + end_month)
请考虑以下内容:-
DROP TABLE IF EXISTS user_balance;
CREATE TABLE IF NOT EXISTS user_balance (email TEXT, amount REAL, description TEXT, year INTEGER, month INTEGER, day INTEGER, created_at TEXT);
INSERT INTO user_balance VALUES
('Fred',5.50,'blah',2019,01,01,'2019-01-01 10:30'),
('Fred',10.50,'blah',2019,01,02,'2019-01-01 10:30'),
('Fred',15.50,'blah',2019,01,13,'2019-01-01 10:30'),
('Fred',20.50,'blah',2019,02,04,'2019-01-01 10:30'),
('Fred',25.50,'blah',2019,02,05,'2019-01-01 10:30'),
('Mary',145.25,'blah',2019,01,01,'2019-01-01 10:30'),
('Mary',145.25,'blah',2019,01,02,'2019-01-01 10:30'),
('Mary',145.25,'blah',2019,01,13,'2019-01-01 10:30'),
('Mary',145.25,'blah',2019,02,04,'2019-01-01 10:30'),
('Mary',145.25,'blah',2019,02,05,'2019-01-01 10:30'),
('Joan',345.25,'blah',2019,01,01,'2019-01-01 10:30'),
('Joan',345.25,'blah',2019,01,02,'2019-01-01 10:30'),
('Joan',345.25,'blah',2019,01,13,'2019-01-01 10:30'),
('Joan',345.25,'blah',2019,02,04,'2019-01-01 10:30'),
('Joan',345.25,'blah',2019,02,05,'2019-01-01 10:30'),
('Fred',45.25,'blah',2018,01,01,'2019-01-01 10:30'),
('Fred',45.25,'blah',2018,01,02,'2019-01-01 10:30'),
('Fred',45.25,'blah',2018,01,13,'2019-01-01 10:30'),
('Fred',45.25,'blah',2018,02,04,'2019-01-01 10:30'),
('Fred',45.25,'blah',2018,02,05,'2019-01-01 10:30'),
('Mary',145.25,'blah',2018,01,01,'2019-01-01 10:30'),
('Mary',145.25,'blah',2018,01,02,'2019-01-01 10:30'),
('Mary',145.25,'blah',2018,01,13,'2019-01-01 10:30'),
('Mary',145.25,'blah',2018,02,04,'2019-01-01 10:30'),
('Mary',145.25,'blah',2018,02,05,'2019-01-01 10:30'),
('Joan',345.25,'blah',2018,01,01,'2019-01-01 10:30'),
('Joan',345.25,'blah',2018,01,02,'2019-01-01 10:30'),
('Joan',345.25,'blah',2018,01,13,'2019-01-01 10:30'),
('Joan',345.25,'blah',2018,02,04,'2019-01-01 10:30'),
('Joan',345.25,'blah',2018,02,05,'2019-01-01 10:30')
;
SELECT email, sum(amount) AS balance, year, month
FROM user_balance
WHERE
((year * 100) + month) BETWEEN ((2018 * 100) + 09) AND ((2019 * 100) + 09)
GROUP BY email,year,month ;
SELECT email, sum(amount) AS balance, year, month
FROM user_balance
WHERE
((year * 100) + month) BETWEEN ((2018 * 100) + 09) AND ((2019 * 100) + 09)
and email = 'Mary'
GROUP BY email,year,month;
此
两个结果是:-
和
要与Android一起使用并使用SQLiteDatabase query方法返回游标,则可以使用以下方法:-
public Cursor getUserBalance(String email, int start_year, int start_month, int end_year, int end_month) {
String[] columns = new String[]{
KEY_EMAIL,
"sum(" + KEY_AMOUTNT + ") AS balance",
KEY_YEAR,
KEY_MONTH
};
String whereclause = "((year * 100) + month) BETWEEN ((? * 100) + ?) AND ((? * 100) + ?) and email = ?";
String[] whereargs = new String[]{
String.valueOf(start_year),
String.valueOf(start_month),
String.valueOf(end_year),
String.valueOf(end_month),
email
};
String groupbyclause = KEY_EMAIL + "," + KEY_YEAR + "," + KEY_MONTH;
SQLiteDatabase db = this.getWritableDatabase();
return db.query(TABLE_USER_BALANCE,columns,whereclause,whereargs,groupbyclause,null,null);
}
getUserBalanceAsCursor
(显然,随后将相应地更改以下内容)。 以上内容实际上并未返回特定用户/月的余额,但对于其他情况可能有用。要返回余额(假设是双倍),则以下方法利用先前的方法在特定月份执行此操作:-
public double getUserBalance(String email, int year, int month) {
double rv = 0.0;
Cursor csr = getUserBalance(email,year,month,year,month);
if (csr.moveToFirst()) {
rv = csr.getDouble(csr.getColumnIndex("balance"));
}
csr.close();
return rv;
}