0

I create a android sql database , every thing is fine at beginning.

But i find an issue that is someone enter a single day like 2017/9/8 not 2017/9/08 , my order by date desc is not working.

Here is my table , i want to sort the row by Date: enter image description here

It is no working when the day is 2017/8/7 and 2017/9/7

enter image description here

Here is my sort date code: //Sort date : Latest to Old date

public List<Contact> sortingDate() {
    List<Contact> contactList = new ArrayList<>();
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_CONTACTS +" ORDER BY " +"Date DESC",null);
    //looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            Contact contact = new Contact();
            contact.setID(Integer.parseInt(cursor.getString(0)));
            contact.setDate(cursor.getString(1));
            contact.setBeforeMorning(cursor.getString(2));
            contact.setAfterMorning(cursor.getString(3));
            contact.setBeforeNoon(cursor.getString(4));
            contact.setAfterNoon(cursor.getString(5));
            contact.setBeforeNight(cursor.getString(6));
            contact.setAfterNight(cursor.getString(7));
            System.out.println("The result is :" + cursor.getString(1));
            //Adding contact to list
            contactList.add(contact);
        } while (cursor.moveToNext());
    }

    return contactList;
}

It looks like when the day number is single will cause the issue, i try to order by orthers , they are no working , i don't know how to figure it out.

Any help would be appreciated . Thanks in advance.

I create the database, TEXT is date type:

@Override
public void onCreate(SQLiteDatabase db) {
    System.out.println("table is here");
    String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
            + KEY_ID + " INTEGER PRIMARY KEY," + KEY_DATE + " TEXT,"
            + KEY_BMORNING + " TEXT," + KEY_AMORNING + " TEXT,"
            + KEY_BNOON + " TEXT," + KEY_ANOON + " TEXT,"
            + KEY_BNIGHT + " TEXT," + KEY_ANIGHT + " TEXT" +
            ")";
    db.execSQL(CREATE_CONTACTS_TABLE);

}
Morton
  • 5,380
  • 18
  • 63
  • 118
  • 2
    What is the datatype of `date`? Hint: If it's `(n)varchar` that's the problem. – HoneyBadger Sep 11 '17 at 14:13
  • 1
    Refer https://stackoverflow.com/questions/14091183/sqlite-order-by-date – Pritesh Patel Sep 11 '17 at 14:14
  • 3
    SQLite has no formal date type, i.e. your dates are being stored as text. You _are_ correctly storing your dates in an ISO format however. The obvious fix here would be to make sure that you always store the month and day components with _two_ digits, not just one, even if there is only one significant figure. – Tim Biegeleisen Sep 11 '17 at 14:14
  • Text is the date type. – Morton Sep 11 '17 at 14:27
  • Thanks @PriteshPatel , but ORDER BY date(dateColumn) DESC can not fix my problem. – Morton Sep 11 '17 at 14:41
  • I gave you an answer below which should work for you. Be it noted that you should seriously consider fixing the way you store dates. – Tim Biegeleisen Sep 11 '17 at 15:02

3 Answers3

2

Warning: The SQLite query you are about to see is ugly and should not be repeated at home, unless you totally messed up your date format, in which case you might have no other choice.

We can try doing an ORDER BY which builds out the correct two digit month and day for each date. Note that in the case of your data, this necessitates padding single digit months and days with zero.

SELECT *
FROM contacts
ORDER BY
    SUBSTR(Date, 1, 4) DESC,
    CASE WHEN INSTR(SUBSTR(Date, 6), '/') = 2
         THEN '0' || SUBSTR(Date, 6, 1)
         ELSE SUBSTR(Date, 6, 2) END DESC,
    CASE WHEN LENGTH(SUBSTR(SUBSTR(Date, 6), INSTR(SUBSTR(Date, 6), '/') + 1)) = 1
         THEN '0' || SUBSTR(SUBSTR(Date, 6), INSTR(SUBSTR(Date, 6), '/') + 1)
         ELSE SUBSTR(SUBSTR(Date, 6), INSTR(SUBSTR(Date, 6), '/') + 1) END DESC;

Note that the correct long term solution would be for you to store all months and days as two digit numbers, padding with zero on the left in the case of single digits (your years would most likely always be 4 digits).

Here is a link to a demo which demonstrates the logic of the above query. Note that I created it using MySQL, because SQLite is not supported, but other than having to replace || with CONCAT, the query is identical.

Demo

Here is the output which shows the correct order along with the year, month, and day components correctly being extracted:

enter image description here

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • Thank you very much , you even show the Demo result , i try your code , it works ! I will study your code , because it still complicated for me . Thank you again , Blessing. – Morton Sep 11 '17 at 15:28
  • Hi Tim, i found an issue when my android device is under 4.4.4, it shows `no such function: INSTR`. There is another answer i found is LIKE , but its not suitable for my case obviously. Can i get some tips from your idea? Thank you. – Morton Dec 13 '17 at 12:20
  • @徐博俊 Rather than invalidating your previous question, I think it would be better if you just fix your date formats. Store them in an ISO format and you won't need such an ugly query. If you really must proceed, then the next best thing would be to open a new question. – Tim Biegeleisen Dec 13 '17 at 13:03
  • Actually i have asked https://stackoverflow.com/questions/47790323/sqliteexception-no-such-function-instr-code-1-under-android-4-44, i don't not sure its have another solution or not. – Morton Dec 13 '17 at 14:30
  • Hi Tim, i have give up and change my code , i get all of my data from sql and change the date format then save it ! Its more easy for every thing i want to operator. Thanks for your advice before. – Morton Dec 15 '17 at 01:44
  • 1
    Happy to help you out. Yes, storing dates in ISO `yyyy-mm-dd` format is definitely the way to go long term. This answer might help out someone else temporarily with a similar problem to yours. – Tim Biegeleisen Dec 15 '17 at 01:46
1

i think because you are sorting by a string value...

try something like ORDER BY CAST(Date as DATE) DESC

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
Peter G.
  • 19
  • 3
1

Fetch all the data without any ordering and then perform ordering on the List using custom comparator

class DateComparator implements Comparator<Contact>
{
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
    public int compare(Contact lhs, Contact rhs)
    {
        return dateFormat.parse(lhs.getDate()).compareTo(dateFormat.parse(rhs.getDate()));
    }
}

Use above comparator to order by date

List<Contact> contactList = new ArrayList<>();
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_CONTACTS,null);
    //looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            Contact contact = new Contact();
            contact.setID(Integer.parseInt(cursor.getString(0)));
            contact.setDate(cursor.getString(1));
            contact.setBeforeMorning(cursor.getString(2));
            contact.setAfterMorning(cursor.getString(3));
            contact.setBeforeNoon(cursor.getString(4));
            contact.setAfterNoon(cursor.getString(5));
            contact.setBeforeNight(cursor.getString(6));
            contact.setAfterNight(cursor.getString(7));
            System.out.println("The result is :" + cursor.getString(1));
            //Adding contact to list
            contactList.add(contact);
        } while (cursor.moveToNext());
    }

Collections.sort(contactList, new DateComparator());
Rajan Kali
  • 12,627
  • 3
  • 25
  • 37
  • Thanks for your reply , the answer and yours are a little complicated for me , but i got the solution from another . Blessing. – Morton Sep 11 '17 at 15:49