vendredi 31 juillet 2015

Android SQLite query missing date

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