Jak zdobyć ostatni rekord z Sqlite?


96

Mam jeden stół question_tablei jeden ImageButton(z tyłu ). Po kliknięciu przycisku Wstecz muszę pobrać ostatni wstawiony rekord z bazy danych .

Mój wiersz zawiera następujące kolumny: question, optionA, optionB, optionC, optionD, i muszę danych do wykorzystania na mój Activity. Tworzę jedną metodę w bazie danych, ale nie działa.

Oto kod w celach informacyjnych:

Wyciąg z MySQLiteHelper.java :

public List<ObjectiveWiseQuestion> getLastInsertQuestion()
{
    // long index = 0;
    List<ObjectiveWiseQuestion>LocwiseProfileList=new ArrayList<ObjectiveWiseQuestion>();
    db = getReadableDatabase();
    Cursor cursor = db.query(
            "sqlite_sequence",
            new String[]{"seq"},
            "name = ?",
            new String[]{TABLE_QUESTION},
            null,
            null,
            null,
            null );

    if (cursor.moveToFirst())
    {
        do {
            ObjectiveWiseQuestion owq= new ObjectiveWiseQuestion();

            owq.setQuestion(cursor.getString(2));
            owq.setOptionA(cursor.getString(3));
            owq.setOptionB(cursor.getString(4));
            owq.setOptionC(cursor.getString(5));
            owq.setOptionD(cursor.getString(6));
            owq.setCorrectOption(cursor.getString(7));
            LocwiseProfileList.add(owq);
        } while(cursor.moveToNext());

        db.close();
    }

    return LocwiseProfileList;
}

OnClickListnerz AddQuestionActivity.java

imgBack.setOnClickListener( new View.OnClickListener() 
{                       
    @Override
    public void onClick(View v) 
    {
        msg();
        emptyFormField();

        try {
            final List<ObjectiveWiseQuestion> LocWiseProfile =  db.getLastInsertQuestion();       

            for (final ObjectiveWiseQuestion cn : LocWiseProfile)
            {   
                db=new MySQLiteHelper(getBaseContext());
                db.getWritableDatabase();
                txtQuestion.setText(cn.getQuestion());
                txtOptionA.setText(cn.getOptionA());
                txtOptionB.setText(cn.getOptionB());
                txtOptionC.setText(cn.getOptionC());
                txtOptionD.setText(cn.getOptionD());
                txtCorrectOption.setText(cn.getCorrectOption());
                db.close();
            }
        } catch(Exception e) {
            e.printStackTrace();
        }           
    }
});

Proszę, daj mi jakąś wskazówkę.

Odpowiedzi:


188

Spróbuj tego:

SELECT * 
    FROM    TABLE
    WHERE   ID = (SELECT MAX(ID)  FROM TABLE);

LUB

możesz również skorzystać z rozwiązania:

SELECT * FROM tablename ORDER BY column DESC LIMIT 1;

25
To bardzo zła prośba w tym celu, ponieważ sqliteprzed zwróceniem wyniku Stephen Nguyen powinien posortować wszystkie rekordy według ich identyfikatora (wolno), DESCa następnieLIMIT 1
Artem Zinnatullin

@Hasmukh cześć govind tutaj .. chcesz zrobić menu satelitarne w prawym dolnym rogu ... zrobiłeś to ..?
Govind Rathod,

@Govind tutaj jest link referencyjny, może ci pomóc, github.com/siyamed/android-satellite-menu/issues/3
Hasmukh

@Hasmukh, jeśli załóżmy, że identyfikator kolumny to nie tylko „AUTOINCREMENT”, ale coś innego, unikalnego ... czy nadal działa to rozwiązanie?
Choletski

1
Wydaje się, że w tej i innych odpowiedziach istnieje nieokreślone założenie, że kolumna, według której sortują, stale rośnie. Dotyczy to kolumn z automatycznym zwiększaniem, ale nie każda tabela ma taką kolumnę.
LarsH,

204

Myślę, że najlepsza odpowiedź jest nieco rozwlekła, po prostu użyj tego

SELECT * FROM table ORDER BY column DESC LIMIT 1;

1
„Najlepsza odpowiedź” nie zawsze pozostaje pierwszą odpowiedzią. Masz na myśli Hasmukha?
LarsH,

czasami podaje przedostatnią wartość z jakiegoś nieznanego powodu ... przez większość czasu działa dobrze
MSD

Jeśli kolumna jest oznaczona AUTOINCREMENT, wówczas opcja SELECT MAX (ID) jest lepsza. Używając CLI wykonaj „EXPLAIN QUERY PLAN <query>” Twoje zapytanie skutkuje pełnym skanowaniem tabeli, podczas gdy SELECT MAX (ID) skutkuje znacznie szybszym wyszukiwaniem.
Brian Heilig

23

Aby uzyskać ostatni rekord ze swojego stołu ...

 String selectQuery = "SELECT  * FROM " + "sqlite_sequence";
 Cursor cursor = db.rawQuery(selectQuery, null);
  cursor.moveToLast();

Powinieneś dodać instrukcję WHERE = TABLE_NAME, gdy twoja baza danych SQLite ma więcej niż jedną tabelę
aphoe

@aphoe Nie potrzebuje WHERE = TABLE_NAME, ponieważ „sqlite_sequence” to odwołanie do tabeli.
apkisbossin

Nie ma żadnej gwarancji, że ostatni rekord w nieposortowanym zapytaniu będzie ostatnim rekordem tabeli. Założę się, że to działa „często”. Nie możesz jednak na tym polegać.
Anders 8

13

Oto prosty przykład, który po prostu zwraca ostatnią linię bez potrzeby sortowania czegokolwiek z żadnej kolumny:

"SELECT * FROM TableName ORDER BY rowid DESC LIMIT 1;"       

To najlepsza odpowiedź, dzięki.
Josef Kvita


8

Jeśli masz już kursor, to w ten sposób możesz uzyskać ostatni rekord z kursora:

cursor.moveToPosition(cursor.getCount() - 1);
//then use cursor to read values

czy istnieje sposób na uzyskanie tego poprzez utworzenie kursora w zapytaniu getContentResolver ().?
ralphgabb

Możesz po prostu użyć kursora.moveToLast ();
Anant Shah

2

Załóżmy, że szukasz ostatniego wiersza tabeli dbstr.TABNAME w kolumnie INTEGER o nazwie „_ID” (na przykład BaseColumns._ID), ale może to być dowolna inna kolumna.

public int getLastId() {
    int _id = 0;
    SQLiteDatabase db = dbHelper.getReadableDatabase();
    Cursor cursor = db.query(dbstr.TABNAME, new String[] {BaseColumns._ID}, null, null, null, null, null);

    if (cursor.moveToLast()) {
        _id = cursor.getInt(0);
    }

    cursor.close();
    db.close();
    return _id;
}

2

Po prostu możesz się poruszać Cursor moveToLast (); metoda zapewnia przejście do ostatniego rekordu

cursor.moveToLast();

2

Chciałem zachować moją tabelę, ciągnąc w jednym wierszu, który daje mi ostatnią wartość w określonej kolumnie tabeli. Zasadniczo chciałem zastąpić tę LAST()funkcję w programie Excel i to zadziałało.

, (Select column_name FROM report WHERE rowid = (select last_insert_rowid() from report))

1

Inną opcją jest użycie SQLite LAST_VALUE() funkcji w następujący sposób.

Biorąc pod uwagę tę tabelę:

+--------+---------+-------+
| OBJECT |  STATUS |  TIME |
+--------+---------+-------+
|        |         |       |
| 1      |  ON     |  100  |
|        |         |       |
| 1      |  OFF    |  102  |
|        |         |       |
| 1      |  ON     |  103  |
|        |         |       |
| 2      |  ON     |  101  |
|        |         |       |
| 2      |  OFF    |  102  |
|        |         |       |
| 2      |  ON     |  103  |
|        |         |       |
| 3      |  OFF    |  102  |
|        |         |       |
| 3      |  ON     |  103  |
+--------+---------+-------+

Możesz uzyskać ostatni status każdego obiektu za pomocą następującego zapytania

SELECT                           
    DISTINCT OBJECT,             -- Only unique rows
    LAST_VALUE(STATUS) OVER (    -- The last value of the status column
        PARTITION BY OBJECT      -- Taking into account rows with the same value in the object column
        ORDER by time asc        -- "Last" when sorting the rows of every object by the time column in ascending order
        RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING    -- Take all rows in the patition
    ) as lastStatus
FROM
    TABLE

Wynik wyglądałby następująco:

+--------+--------------+
| OBJECT |  LAST_STATUS |
+--------+--------------+
|        |              |
| 1      |  ON          |
|        |              |
| 2      |  ON          |
|        |              |
| 3      |  ON          |
+--------+--------------+

0

w sqlite jest tabela o nazwie sqlite_sequence, ta tabela zawiera nazwę tabeli i jej ostatni numer identyfikacyjny (jeśli identyfikator jest automatycznie zwiększany).

Aby więc uzyskać ostatni wiersz w tabeli, po prostu wpisz:

Select * from TABLENAME where id=(SELECT * from sqlite_sequence where name ='TABLENAME')

0

W poprzednich odpowiedzi zakładają , że istnieje zwiększając całkowitą kolumna ID, więc MAX(ID)daje ostatni wiersz. Ale czasami klawisze są typu tekstowego , a nie uporządkowane w przewidywalny sposób. Aby więc wziąć ostatni 1 lub N wierszy (# Nrows #), możemy zastosować inne podejście :

Select * From [#TableName#]  LIMIT #Nrows# offset cast((SELECT count(*)  FROM [#TableName#]) AS INT)- #Nrows#
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.