Вы можете выполнить запрос, который использует функцию sum (x) для данных, которые были сгруппированы с помощью предложения GROUP BY.
- , где x представляет имя столбца.
sumtion (x) fundtion - это агрегатная функция, которая возвращает результат добавления столбца 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 сохранено, для feb 2 сохранено и т. Д.), Возникают проблемы, поскольку 20192 (февраль 2019) больше 201912 (сортировка целесообразна, если просто объединяется), поэтому некоторыетребуется манипулирование, например, путем умножения года на 100 и добавления.
Таким образом, для выбора диапазона дат в предложении WHERE с использованием предложения BETWEEN можно использовать что-то вроде: -
WHERE (year * 100) + month BETWEEN ((start_year * 100) + start_month) AND ((end_year * 100) + end_month)
- Приведенное выше подразумевается для всех учетных записей электронной почты (для каждой учетной записи электронной почты будут отдельные строки / суммы).Для одной учетной записи электронной почты будет добавлено предложение WHERE.
Пример SQL
Рассмотрим следующее: -
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;
Это
- УДАЛЯЕТ и СОЗДАЕТ таблицу user_balance (дляудобство запуска / тестирования / изменения) в примере.
- Добавляет некоторые данные тестирования для 3 электронных писем / пользователей, каждый из которых имеет данные за 2 месяца в течение 2 лет.
- Выбор суммы дохода (суммы) за каждый месяц для всех электронных писем / пользователей на даты в диапазоне с сентября 2018 г. (2018 г. 09) - сентябрь 2019 г. (2019 г. 09).
- Как указано выше, но для определенного адреса электронной почты / пользователя.
Два результата: -
![enter image description here](https://i.stack.imgur.com/FEA9c.png)
и
![enter image description here](https://i.stack.imgur.com/ermgb.png)
4 Android (Java)
Для использования с Android и использования базы данных SQLiteDatabase метод для возврата курсора, который вы могли бы затем использовать что-то вроде: -
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);
}
- NOTE приведенный выше код в принципе, этоне был протестирован или запущен и, следовательно, может содержать ошибки.
- Учитывая следующее, вы можете назвать этот метод более описательным, например, возможно,
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;
}
- ПРИМЕЧАНИЕ вышеизложенное является в принципекод, он не был протестирован или запущен и поэтому может содержать ошибки.