Marc Reichelt: SQLite: laufenden Zähler in SELECT erzeugen (sinnvoll?)

Hallo an alle,

in einer Android-App verwalte ich die Daten in einer SQLite-Datenbank. Die Abfragen sind normalerweise recht simpel, doch jetzt habe ich eine kleine Herausforderung der ich bislang so noch nicht begegnet bin: Ich benötige eine laufende Nummer. Als Beispiel habe ich hier eine Liste von Früchten (wie man sieht mit automatisch eingefügten IDs, die damit nicht zur Sortierung herhalten können):
id   | bezeichnung
-----+------------
2    | Apfel
5    | Birne
3    | Traube
42   | Orange

Die laufende Nummer soll immer nach der Sortierung "bezeichnung" erfolgen, also beispielsweise wie folgt:
id   | bezeichnung | laufende_nummer
-----+-------------+----------------
2    | Apfel       | 1
5    | Birne       | 2
42   | Orange      | 3
3    | Traube      | 4

Das soll auch der Fall bleiben wenn ich nur eine Teilmenge der Tabelle bekomme (Apfel und Birne nicht ausgewählt):
id   | bezeichnung | laufende_nummer
-----+-------------+----------------
42   | Orange      | 3
3    | Traube      | 4

Und die laufende Nummer soll sich automatisch mit ändern, wenn weitere Elemente in die Tabelle eingefügt werden, Beispiel an "Ananas" (Apfel und Birne sind weiterhin in der Tabelle, werden aber nicht ausgewählt):
id   | bezeichnung | laufende_nummer
-----+-------------+----------------
43   | Ananas      | 1
42   | Orange      | 4
3    | Traube      | 5

Wie kann ich das am Besten in SQLite bewerkstelligen? Ich könnte den Counter natürlich als neues Feld einfügen und mit jeder Änderung der Tabelle für jede Zeile neu setzen, aber eventuell gibt es da ja eine bessere Lösung. :-)

Vielen Dank & freundliche Grüße

Marc Reichelt || http://www.marcreichelt.de/

--
DPRINTK("Last time you were disconnected, how about now?");
        linux-2.6.6/drivers/net/tokenring/ibmtr.c
Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
  1. Hallo

    Ich bin auf dem Gebiet zwar kein Experte, aber das hört sich für mich nach ROWID bzw. INTEGER PRIMARY KEY an (siehe dazu auch AUTOINCREMENT).

    Waldi

    1. Hallo Waldi,

      Ich bin auf dem Gebiet zwar kein Experte, aber das hört sich für mich nach ROWID bzw. INTEGER PRIMARY KEY an (siehe dazu auch AUTOINCREMENT).

      Nein, das geht leider nicht (das wäre prinzipiell fast das Gleiche wie die ID zu verwenden). Prinzipiell können nämlich neue Elemente hinzugefügt werden, die von der Sortierung her irgendwo zwischen den vorhandenen Elementen angesiedelt werden können.

      Grüße

      Marc Reichelt || http://www.marcreichelt.de/

      --
      DPRINTK("Last time you were disconnected, how about now?");
              linux-2.6.6/drivers/net/tokenring/ibmtr.c
      Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
      1. Hallo Marc,

        Nein, das geht leider nicht (das wäre prinzipiell fast das Gleiche wie die ID zu verwenden).

        effektiv suchst Du so etwas wie Oracles ROWNUM, was etwas ganz anderes ist als die ROWID. Beim kurzen Überfliegen der Doku ist mir keine passende Funktion aufgefallen.

        Idee: Nutze für die Daten eine (temporäre) Tabelle, die Du per CREATE TABLE ... AS SELECT mit einer ORDER-BY-Klausel füllst. Deren ROWID passt genau auf Deine im Ausgangspost gestellten Anforderungen, siehe http://www.sqlite.org/lang_createtable.html.

        Freundliche Grüße

        Vinzenz

        1. Hallo Vinzenz,

          effektiv suchst Du so etwas wie Oracles ROWNUM, was etwas ganz anderes ist als die ROWID. Beim kurzen Überfliegen der Doku ist mir keine passende Funktion aufgefallen.

          Idee: Nutze für die Daten eine (temporäre) Tabelle, die Du per CREATE TABLE ... AS SELECT mit einer ORDER-BY-Klausel füllst. Deren ROWID passt genau auf Deine im Ausgangspost gestellten Anforderungen, siehe http://www.sqlite.org/lang_createtable.html.

          Vielen Dank für die Antwort! Ich denke aber dass es sich in diesem Falle für mich sogar lohnt, auf die temporäre Tabelle zu verzichten und diesen Counter manuell als Spalte einzupflegen. Updates auf die Tabelle werden immerhin nicht allzuoft gemacht und die Tabelle wird voraussichtlich nicht mehr als 2000 Zeilen enthalten, insofern sollte das in Ordnung sein. Gibt es wenigstens für die Zuweisung der Zeilennummer an die Spalte eine Generallösung, oder wäre ROWNUM oder eine temporäre Tabelle auch hier benötigt?

          Grüße

          Marc Reichelt || http://www.marcreichelt.de/

          --
          DPRINTK("Last time you were disconnected, how about now?");
                  linux-2.6.6/drivers/net/tokenring/ibmtr.c
          Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
          1. Hallo Marc,

            Idee: Nutze für die Daten eine (temporäre) Tabelle, die Du per CREATE TABLE ... AS SELECT mit einer ORDER-BY-Klausel füllst. Deren ROWID passt genau auf Deine im Ausgangspost gestellten Anforderungen, siehe http://www.sqlite.org/lang_createtable.html.

            Ich denke aber dass es sich in diesem Falle für mich sogar lohnt, auf die temporäre Tabelle zu verzichten und diesen Counter manuell als Spalte einzupflegen.

            die Pflege des Counters ist bei allen INSERT- und DELETE-Operationen erforderlich - sowie bei UPDATE-Operationen, die den Inhalt der Sortierspalte verändern. Könnte mit Triggern klappen, auch ohne temporäre Tabelle, mit einem CASE-WHEN-THEN-ELSE-Konstrukt.

            Freundliche Grüße

            Vinzenz