SQLite - Select Abfrage um Datensätze zu gruppieren

  • Antworten:5
BlackDroid
  • Forum-Beiträge: 18

19.01.2012, 17:31:25 via Website

Hallo zusammen,

ich hänge an einem (wahrscheinlichen) Anfänger-Problem.
Ich habe in meiner Datenbank mehrere hundert Datensätze - diese möchte ich jetzt nach einer bestimmten Eigenschaft gruppiert abrufen.
Beispiel:
Ich habe eine Tabelle in der ich Daten vom Typ "Auto" gespeichert habe - jedes Auto hat als Eigenschaft eine Farbe. Jetzt möchte ich gerne eine Abfrage ausführen, welche mir alle Autos - gruppiert nach den Farben zurückliefert. Dann kann ich wiederrum durch die einzelnen Gruppen iterieren, um eben weitere Dinge vorzunehmen. Meine Abfrage:

1cursor = mDBManager.getReadableDatabase().query(
2 "Cars",
3 _columns,
4 null,
5 null,
6 Car.Color, //groupby
7 null,
8 null);
9 return cursor;

Die Gruppierung funktioniert auch einwandfrei - allerdings stehen in meinem Cursor nach der Abfrage immer nur die letzte Zeile der jeweiligen Gruppe.

Habe ich also im oben genannten Beispiel zwei Auto-Farben - hat mein Cursor genau zwei Datensätze als Inhalt. Die jeweils letzte Zeile der jeweiligen Gruppierung.

Habt Ihr diesbezüglich eine Lösung? bzw. hab ich da wohl noch etwas nicht auf dem Schirm.

thx....Grüße

Antworten
Florian B.
  • Forum-Beiträge: 284

19.01.2012, 19:01:54 via Website

Ich glaube eher du verstehst den group by Befehl falsch. Deine Abfrgae macht genau das was sie soll. Sie fast alle Einträge die die gleiche Farbe haben zusammen, dabei bleibt dann einfach jedweils der letzte Eintrag über. Normalerweise verwendet man group by um mit eine Aggregationsfunktion wie z.B. sum() (Summieren aller Einträge) zu arbeiten, und damit beispielsweise alle Preise der Autos zusammen zu zählen, die die gleiche Farbe haben.

Ich denke du willst eher alle Einträge in deiner Datenbank die eine bestimmte Farbe haben. In diesem Fall brauchst du kein group by, sonder eine select Abfrage mit einer where Bedingung.

Antworten
Gelöschter Account
  • Forum-Beiträge: 24

19.01.2012, 19:57:44 via Website

Gruppiert oder sortiert? Was in der Darstellung gruppiert wird sortiert man im SQL ;-)

Wenn Du alle Autos nach Farben sortiert haben möchtest dann schmeiß den GROUP BY raus und bau einen ORDER BY Car.Color ein.

Wenn Du gruppieren möchtest dann müsstest Du noch mitteilen was das Aggregat sein soll (e.g. Anzahl aller Autos pro Farbe, ...).

Gruß
Harald

— geändert am 19.01.2012, 19:59:40

Antworten
BlackDroid
  • Forum-Beiträge: 18

19.01.2012, 21:53:22 via Website

...danke für die Antworten.
Das mit dem groupby Befehl habe ich geschluckt.

Noch mal kurz zu dem was ich realisieren möchte bzw. um meine SQL-Wissenslücke zu stopfen:

Ich kenne die einzelnen Farben der Autos nicht, deswegen kann ich nicht direkt einen where Befehl absetzen. Darum ging ich davon aus das ich die Datensätze nach den Farben "gruppieren" kann - um dann wieder durch die separierten "Farb"-Gruppen zu iterieren.
Jedes Auto Objekt hat eine Eigenschaft "Status" (Enumeration), welche ich für die einzelnen Farb-Gruppen ermitteln und aufaddieren muss.
(Gruppe "Rot": Status.Canceled = 12 mal usw.)

Das ist der Hintergrund.

Wie würde die optimale Lösung aussehen?

Ich könnte erst die Datensätze gruppieren bzw. erhalte dann pro Farbe einen Datensatz im Cursor. Dann kann ich pro Farbe einen where-Befehl absetzen und erhalte dann die gewünschten Datensätze wiederum in einem Cursor.
-> 2 SQL Abfragen

thx...!

Antworten
Felix
  • Forum-Beiträge: 259

19.01.2012, 22:30:16 via Website

Tach!

BlackDroid
Ich habe eine Tabelle in der ich Daten vom Typ "Auto" gespeichert habe - jedes Auto hat als Eigenschaft eine Farbe. Jetzt möchte ich gerne eine Abfrage ausführen, welche mir alle Autos - gruppiert nach den Farben zurückliefert. Dann kann ich wiederrum durch die einzelnen Gruppen iterieren, um eben weitere Dinge vorzunehmen.

Wie schon gesagt wurde, macht die GROUP BY-Klausel was anderes als du vermutest. Ebenfalls wurde schon gesagt, dass du deine Datensätze für die Gruppierung, die du dir vorstellst, lediglich sortieren musst. Die Ergebnismenge einer SQL-Abfrage ist immer flach und nicht weiter strukturiert. Wenn du Datensätze zum Anzeigen unter Zwischenüberschriften zusammenfassen oder gruppenweise einrahmen oder … möchtest, lautet dein Stichwort Gruppenwechsel. Man merkt sich vom aktuellen Datensatz die Gruppier-Eigenschaft und vergleicht beim nächsten Durchlauf der Abfrageschleife den nun aktuellen Wert mit dem vorher gemerkten. Sind sie unterschiedlich fand ein Gruppenwechsel statt und es kann beispielsweise die Zwischenüberschrift vor den eigentlichen Daten des Datensatzes angezeigt werden.

Edit:
Ich könnte erst die Datensätze gruppieren bzw. erhalte dann pro Farbe einen Datensatz im Cursor. Dann kann ich pro Farbe einen where-Befehl absetzen und erhalte dann die gewünschten Datensätze wiederum in einem Cursor.
-> 2 SQL Abfragen

In Wirklichkeit sind es für jede Gruppe eine plus eine für die Gruppen. Solche rekursiven Anfragen lässt man normalerweise ungern gegen ein DBMS laufen, weil das viel mehr kostet als nur eine Abfrage. Unter Android mag das anders aussehen, weil hier das DBMS in Form von SQLite mit an Bord ist. Solche Daten würde ich übers Netz jedenfalls nur mit einer Abfrage abfragen wollen. Wenn du Einzelabfragen statt eine nebst Gruppenwechsel machen möchtest, dann wäre die erste Abfrage die nach den Gruppen (eventuell mit DISTINCT, wenn du nicht normalisert hast) und die anderen dann mit WHERE und dem jeweiligen Wert aus der Gruppe.

Im Zusammenhang mit der Darstellung kannst du das über eine ExpandableListView und einen der ExpandableListAdapter erledigen. Die Adapter jedenfalls wollen auch erst einen Gruppen-Cursor und dann nochmal Einzeldaten-Cursor haben.


Felix.

— geändert am 19.01.2012, 22:40:55

Antworten
BlackDroid
  • Forum-Beiträge: 18

20.01.2012, 09:29:51 via Website

Tach!

geschluckt und umgesetzt - muchas gracias!!
Ich sortiere jetzt die Datensätze bereits in der Select- Anweisung und reagiere dann beim Gruppenwechsel...wie es mir empfohlen wurde >_>

thx...& Grüße

Antworten