I have 2 tables one contains users and their data, the other contains payment transactions which are done but not limited to once per month. I'd like to query users who have not paid at least once from the day they were added into the system. My table users table looks like so.
idu fname lname date_added
1 John Doe 2012-01-01 08:00:00
2 Jane Doe 2012-01-01 08:00:00
3 Mary Jane 2012-01-01 08:00:00
4 John Rancho 2012-01-01 08:00:00
My payments table looks like so
payment_id uid payment_date
1 2 2012-01-07 08:00:00
2 3 2013-01-12 08:00:00
3 1 2012-02-01 08:00:00
4 2 2012-02-07 08:00:00
5 3 2013-02-12 08:00:00
6 1 2012-03-01 08:00:00
7 2 2015-04-08 08:00:00
8 1 2014-05-31 08:00:00
9 1 2014-07-31 08:00:00
I would like my results to look like the table shown below where unpaid times is the count of months not paid for and is greater than one.
IDU Name Unpaid Times
2 Jane Doe 3
3 Mary Jane 4
I did the query in PHP and MySQL in a crappy way though I get desired results. I want to transfer the code to Android and SQLite so an otimised query is highly required. My PHP/MySQL code is shown below.
$query = "SELECT idu,fname,lname,date_added,payment_date FROM water_users LEFT JOIN payments ON idu=sold_to GROUP BY (CASE WHEN MONTH(payment_date) IS NULL THEN idu ELSE MONTH(payment_date) END) ORDER BY DATE(payment_date) ASC";
$result = $db->RunQueryForResults($query);
$defaulters = array();
while ($row = $result->fetch_assoc()) {
$start_date = $row['date_added'];
while (strtotime($start_date) < strtotime(getCurrentDate())) {
$current_month = date("Y-m", strtotime($start_date));
$payment_date = date("Y-m", strtotime($row['payment_date']));
if ((strtotime($current_month) !== strtotime($payment_date)) && (strtotime($payment_date) <= strtotime($current_month))) {
$defaulters[] = array(
'idu' => $row['idu'],
'name' => $row['fname'] . " " . $row['lname'],
'defaulted_month' => date("M Y", strtotime($current_month))
);
}
$start_date = date("Y-m-d H:i:s", strtotime("+30 day", strtotime($start_date)));
}
}
I ported the php code to the java code below. Please advise thanks.
ArrayList<HashMap<String, String>> defaulters = new ArrayList<>();
HashMap<Integer, HashMap<String, String>> water_users = new HashMap<>();
String selectQuery = " SELECT "
+ Constants.ID_USER + ","
+ Constants.FNAME + ","
+ Constants.LNAME + ","
+ Constants.DATE_ADDED + " "
+ " FROM " +
Constants.TABLE_PREFIX + Constants.WATER_USERS_TABLE;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
java.util.Date dt = new java.util.Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String currentTime = sdf.format(dt);
GregorianCalendar gcal = new GregorianCalendar();
Date start = sdf.parse(cursor.getString(cursor.getColumnIndex(Constants.DATE_ADDED)));
Date end = sdf.parse(currentTime);
gcal.setTime(start);
boolean exits = false;
while (gcal.getTime().before(end) && !exits) {
String str[] = sdf.format(gcal.getTime()).split("-");
int year = Integer.parseInt(str[0]);
int month = Integer.parseInt(str[1]);
String sql = "SELECT COUNT(" + Constants.ID_SALE + ") AS total_transactions," + Constants.SOLD_TO + ", CAST(strftime('%m', " + Constants.SALE_DATE + ") AS INTEGER) month, CAST(strftime('%Y', " + Constants.SALE_DATE + ") AS INTEGER) year," + Constants.SALE_DATE
+ " FROM " + Constants.SALES_TABLE
+ " WHERE month=" + month
+ " AND year=" + year
+ " AND " + Constants.SOLD_TO + "=" + cursor.getString(cursor.getColumnIndex(Constants.ID_USER));
Cursor cursor2 = db.rawQuery(sql, null);
if (cursor2 != null) {
cursor2.moveToFirst();
}
if (!water_users.containsKey(cursor2.getInt(cursor2.getColumnIndex(Constants.SOLD_TO)))) {
HashMap<String, String> user = new HashMap<>();
user.put(Constants.IDU, cursor.getString(cursor.getColumnIndex(Constants.ID_USER)));
user.put(Constants.FNAME, cursor.getString(cursor.getColumnIndex(Constants.FNAME)));
user.put(Constants.LNAME, cursor.getString(cursor.getColumnIndex(Constants.LNAME)));
water_users.put(cursor2.getInt(cursor2.getColumnIndex(Constants.SOLD_TO)), user);
defaulters.add(user);
} else {
exits = true;
}
gcal.add(Calendar.DAY_OF_MONTH, 1);
}
exits = false;
} while (cursor.moveToNext());
}
Aucun commentaire:
Enregistrer un commentaire