Comment obtenir le dernier enregistrement de Sqlite?

95

J'ai une table question_tableet une ImageButton( arrière ). J'ai besoin d'obtenir le dernier enregistrement inséré de la base de données après avoir cliqué sur le Retour .

Ma ligne contient les colonnes suivantes: question, optionA, optionB, optionC, optionD, et j'ai besoin des données pour une utilisation sur mon Activity. Je crée une méthode dans la base de données mais cela ne fonctionne pas.

Voici le code pour référence:

Extrait de 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;
}

OnClickListnerdepuis 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();
        }           
    }
});

Veuillez me donner un indice.

ADM
la source

Réponses:

188

Essaye ça:

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

OU

vous pouvez également utiliser la solution suivante:

SELECT * FROM tablename ORDER BY column DESC LIMIT 1;
Hasmukh
la source
25
C'est une très mauvaise demande à cet effet car sqlitedevrait trier tous les enregistrements par leur id (lent) avant de renvoyer le résultat, Stephen Nguyen a donné une requête optimale avec DESCetLIMIT 1
Artem Zinnatullin
@Hasmukh hi govind here .. veux faire le menu satelitemenu à droite du coin inférieur ... l'avez-vous fait ..?
Govind Rathod
@Govind voici le lien de référence, il peut vous aider, github.com/siyamed/android-satellite-menu/issues/3
Hasmukh
@Hasmukh, si supposons que l'ID de colonne ne soit pas simplement 'AUTOINCREMENT' mais quelque chose d'autre unique ... fonctionne toujours cette solution?
Choletski
1
Ceci et d'autres réponses semblent avoir une hypothèse non déclarée que la colonne sur laquelle ils sont triés augmente toujours. C'est vrai pour les colonnes à incrémentation automatique, mais toutes les tables n'ont pas une colonne comme celle-là.
LarsH
200

Je pense que la réponse principale est un peu verbeuse, utilisez simplement ceci

SELECT * FROM table ORDER BY column DESC LIMIT 1;
Stephen Nguyen
la source
1
La "première réponse" ne reste pas toujours la première réponse. Voulez-vous dire Hasmukh?
LarsH
parfois, il donne l'avant-dernière valeur pour une raison inconnue ... la plupart du temps, cela fonctionne bien
MSD
Si la colonne est marquée AUTOINCREMENT, SELECT MAX (ID) est préférable. À l'aide de la CLI, exécutez «EXPLAIN QUERY PLAN <query>», votre requête entraîne une analyse complète de la table, tandis que SELECT MAX (ID) entraîne une recherche beaucoup plus rapide.
Brian Heilig
23

Pour obtenir le dernier enregistrement de votre table ..

 String selectQuery = "SELECT  * FROM " + "sqlite_sequence";
 Cursor cursor = db.rawQuery(selectQuery, null);
  cursor.moveToLast();
5hssba
la source
Vous devez ajouter l'instruction WHERE = TABLE_NAME lorsque votre base de données SQLite a plus d'une table
aphoe
@aphoe Il n'a pas besoin de WHERE = TABLE_NAME car "sqlite_sequence" est la référence de la table.
apkisbossin le
Je ne connais aucune garantie que le dernier enregistrement d'une requête non triée sera le dernier enregistrement de la table. Je parie que cela fonctionne "souvent". Vous ne pouvez cependant pas vous y fier.
Anders8
11

Voici un exemple simple qui renvoie simplement la dernière ligne sans avoir besoin de trier quoi que ce soit dans une colonne:

"SELECT * FROM TableName ORDER BY rowid DESC LIMIT 1;"       
utilisateur4061742
la source
8

Si vous avez déjà le curseur, voici comment vous pouvez obtenir le dernier enregistrement du curseur:

cursor.moveToPosition(cursor.getCount() - 1);
//then use cursor to read values
waqaslam
la source
existe-t-il un moyen d'obtenir cela grâce à la création d'un curseur sur getContentResolver (). query?
ralphgabb
Vous pouvez simplement utiliser cursor.moveToLast ();
Anant Shah
2

Simplement simple, vous pouvez vous déplacer avec Cursor moveToLast (); la méthode permet de passer au dernier enregistrement

cursor.moveToLast();
Dilavar Malek
la source
2

Je voulais maintenir ma table tout en tirant sur une ligne qui me donne la dernière valeur dans une colonne particulière du tableau. Je cherchais essentiellement à remplacer la LAST()fonction dans Excel et cela a fonctionné.

, (Select column_name FROM report WHERE rowid = (select last_insert_rowid() from report))
j casillas
la source
1

Supposons que vous recherchiez la dernière ligne de la table dbstr.TABNAME, dans une colonne INTEGER nommée "_ID" (par exemple BaseColumns._ID), mais qu'il pourrait s'agir de toute autre colonne de votre choix.

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;
}
Zanna
la source
1

Une autre option consiste à utiliser la LAST_VALUE()fonction SQLites de la manière suivante.

Compte tenu de ce tableau:

+--------+---------+-------+
| 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  |
+--------+---------+-------+

Vous pouvez obtenir le dernier statut de chaque objet avec la requête suivante

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

Le résultat ressemblerait à:

+--------+--------------+
| OBJECT |  LAST_STATUS |
+--------+--------------+
|        |              |
| 1      |  ON          |
|        |              |
| 2      |  ON          |
|        |              |
| 3      |  ON          |
+--------+--------------+
Saaru Lindestøkke
la source
0

dans sqlite, il y a une table appelée sqlite_sequence, cette table contient le nom de la table et son dernier numéro d'identification (si l'id est incrémenté automatiquement).

Donc, pour obtenir la dernière ligne d'un tableau, il suffit de mettre:

Select * from TABLENAME where id=(SELECT * from sqlite_sequence where name ='TABLENAME')
briniSoft
la source
0

Les réponses précédentes supposent qu'il existe une colonne ID d' entier incrémentée , donc MAX(ID)donne la dernière ligne. Mais parfois, les touches sont de type texte , non ordonnées de manière prévisible. Donc, pour prendre les 1 ou N dernières lignes (# Nrows #), nous pouvons suivre une approche différente :

Select * From [#TableName#]  LIMIT #Nrows# offset cast((SELECT count(*)  FROM [#TableName#]) AS INT)- #Nrows#
anefeletos
la source