Sqlite Abfrage jede nte zeile auslesen

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
ScooB
User
Beiträge: 54
Registriert: Donnerstag 28. April 2011, 10:47

Hi
ich bin grad dabei Messwerte aus einer Sqlite DB auszulesen.

Ich habe mehrere Tabellen mit Messwerten in den ich z.B. Werte in eimem bestimmten Takt speichere (z.B. 250ms), jetzt möchte ich aus einer Tabelle sagen wird allerdings die Werte im 1000ms Takt auslesen.

Jetzt habe ich das bisher zusammen bekommen.

Code: Alles auswählen

SELECT * FROM "Messert1"
where (TimeStamp BETWEEN '23.10.2012 10:45' AND '23.10.2012 10:48')
AND 
(rowid - (SELECT rowid FROM "Messert1" WHERE TimeStamp > '23.10.2012 10:45' ORDER BY TimeStamp LIMIT 1)) % 2 = 0;
Aber ich habe noch ein Problem mit der rowid da diese nicht fortlaufend in der Tabelle ist, ich würde gern eine rowid bei der Abfrage erstellen geht das??

Gruß ScooB
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hallo,

bitte beschreibe mal das Problem genauer! Zudem achte mal darauf, korrektes Deutsch zu schreiben. Einige Satzfragmente sind komplett unverständlich.

Ich kann aus Deinen bisherigen Schilderungen nicht einmal das Problem erahnen, geschweige denn eine Lösung ersinnen. Was hat z.B. der Takt der Dateneingabe und der -ausgabe mit der Query zu tun? Wieso spielt der überhaupt eine Rolle? Wir wird der Index generiert?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
noisefloor
User
Beiträge: 3882
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

mal abgesehen vom Deutsch ;-)
ich würde gern eine rowid bei der Abfrage erstellen geht das??
Entweder willst du abfragen oder in der Tabelle was schreiben (erstellen) - beides zusammen geht nicht.

Weiterhin schreibst du was von Messwerten im 0,25 oder 1s Takt, dein Timestamp im Beispiel ist aber nur auf eine Minute genau... Da passt was nicht!

Gruß, noisefloor
Benutzeravatar
sparrow
User
Beiträge: 4244
Registriert: Freitag 17. April 2009, 10:28

Bei Datenbanken ist nicht sicher in welcher Reihenfolge Datensätze ausgegeben werden. Es gibt zwar (je nach Datenbank) die Möglichkeit eine "Standardsortierung" für die Tabelel vorzugeben, in der Regel wird aber aus Performancegründen darauf verzichtet. Es liegt also schon einmal an dir für die richtige Reihenfolge zu sorgen, der SQL-Syntax kennt hierfür "ORDER BY".
http://www.sqlite.org/lang_select.html hat geschrieben:If a SELECT statement that returns more than one row does not have an ORDER BY clause, the order in which the rows are returned is undefined.
Du könntest die alle Datensätze holen und diese dann hinteher in Python verwerfen, wenn du nur jeden 2. haben möchtest. Das würde dir die Auswertung jedoch sehr viel schwerer machen. Ich würde lieber sehen, dass ich in der Abfrage den Wert entsprechend selektiert bekomme um dann nach ihm zu gruppieren. In deinem Fall also die Tausendstelsekunden oder ähnliches. Dann kannst du dir auch überlegen, ob du nur den erste Wert nimmst oder alle Werte der Gruppe mittelst.
Je nach Abfrage kann das zwar länger dauern, aber darüber kann man ohne die Daten zu kennen nichts sagen. (Im Zweifelsfall kann man für die Performance der Normalisierung vorziehen und den zu gruppierenden Wert zusätzlich mit in die Datenbank schreiben).
ScooB
User
Beiträge: 54
Registriert: Donnerstag 28. April 2011, 10:47

Sorry :oops:

Also ich zeichne Messwerte in einem bestimmten Takt auf.
Für jeden Wesswert gibt es eine Tabelle die wie folgt aussieht:

CREATE TABLE "Messwert1" (TimeStamp, ID, Name,SignalInterval , Type, Value);

TimeStamp | Name | Interval | Type | Value
26.10.2012 12:55:45 | Var1 | 1000 | INT | 15
26.10.2012 12:55:46 | Var1 | 1000 | INT | 16
26.10.2012 12:55:47 | Var1 | 1000 | INT | 17
26.10.2012 12:55:48 | Var1 | 1000 | INT | 14
usw.

In dem Beispiel oben zeiche ich jede Sekunde Werte auf, die in die DB geschrieben werten. (Es können in einer Tabelle auch unterschiedliche Intervalle vorkommen)
Soweit alles ok.
Ich möchte jetzt Werte aus der DB auslesen aber nicht alle, sondern nur die Werte z.b. jeder zweiten Sekunde.
Ich hoffe bis jetzt ist es noch verständlich.

Wenn nun die folgende Abfrage durchführe:

Code: Alles auswählen

SELECT * FROM "Messert1"
where (TimeStamp BETWEEN '26.10.2012 12:55' AND '26.10.2012 12:59')
AND
(rowid - (SELECT rowid FROM "Messert1" WHERE TimeStamp > '26.10.2012 12:55' ORDER BY TimeStamp LIMIT 1)) % 2 = 0;
bekomme ich fast die das Ergebnis das ich möchte.
Allerdings habe ich das Problem wenn ich in der Tabelle noch einmal den Wert mit einem anderen Takt drin habe z.B.

TimeStamp | Name | Interval | Type | Value
26.10.2012 12:55:45 | Var1 | 1000 | INT | 15
26.10.2012 12:55:46 | Var1 | 1000 | INT | 16
26.10.2012 12:55:46 | Var1 | 500 | INT | 16
26.10.2012 12:55:47 | Var1 | 1000 | INT | 16
26.10.2012 12:55:47 | Var1 | 500 | INT | 17
26.10.2012 12:55:48 | Var1 | 1000 | INT | 14

und ich nun die Abfage noch auf den Intervall begrenze

Code: Alles auswählen

SELECT * FROM "Messert1"
where (TimeStamp BETWEEN '26.10.2012 12:55' AND '26.10.2012 12:59')
AND Interval = 1000 AND
(rowid - (SELECT rowid FROM "Messert1" WHERE TimeStamp > '26.10.2012 12:55' ORDER BY TimeStamp LIMIT 1)) % 2 = 0;
dann ist mein Ergebnis nicht ganz korrekt, die rowid ist eine fortlaufende die SQLite selbst anlegt, jetzt ist es ja so das die Tabelle mit einer angezeigten rowid so aussieht

rowid |TimeStamp | Name | Interval | Type | Value
1 |26.10.2012 12:55:45 | Var1 | 1000 | INT | 15
2 |26.10.2012 12:55:46 | Var1 | 1000 | INT | 16
3 |26.10.2012 12:55:46 | Var1 | 500 | INT | 16
4 |26.10.2012 12:55:47 | Var1 | 1000 | INT | 16
5 |26.10.2012 12:55:47 | Var1 | 500 | INT | 17
6 |26.10.2012 12:55:48 | Var1 | 1000 | INT | 14

dadruch das die einige rowids wegfallen kann ich den Modulo nicht mehr so durchführen.
Habe ich eine möglichkeit eine fortlaufende Aufzählung zu erzeugen anstatt die rowid zu verwenden.

Gruß
ScooB
Benutzeravatar
noisefloor
User
Beiträge: 3882
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

kannst du nicht einen Timestamp schreiben, der eindeutig = genau ist? Das würde die Sache erheblich vereinfachen.
Abgesehen davon ist es IMHO wenig sinnvoll, wie aktuell den Timestamp zu schreiben, weil so der gleich TS 60x und öfter vorkommen kann.

Gruss, noisefloor
ScooB
User
Beiträge: 54
Registriert: Donnerstag 28. April 2011, 10:47

noisefloor hat geschrieben:Hallo,

kannst du nicht einen Timestamp schreiben, der eindeutig = genau ist? Das würde die Sache erheblich vereinfachen.
Abgesehen davon ist es IMHO wenig sinnvoll, wie aktuell den Timestamp zu schreiben, weil so der gleich TS 60x und öfter vorkommen kann.

Gruss, noisefloor
Ok sagen wird ich würde als kleinsten Interval 1 Sekunde haben
Benutzeravatar
noisefloor
User
Beiträge: 3882
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

dann böte ich an, die Daten von der DB nach dem Timestamp sortieren lassen, zurück liefern und in der so erhaltenen Liste jeden 2. Wert zu nutzen (bzw. zu verwerfen).

Zumindest dann, wenn die Datenmenge nicht gigantisch groß ist.

Gruß, noisefloor
ScooB
User
Beiträge: 54
Registriert: Donnerstag 28. April 2011, 10:47

@noisefloor

Es sollte schon in der Abfrage sortiert werden wenn es soweit möglich ist, denn die Datenmenge könnte schon größer werden.

Gruß ScooB
Benutzeravatar
noisefloor
User
Beiträge: 3882
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

das geht den Bordmitteln von SQLite aber wohl nicht... Jetzt kannst du entweder eine "große" SQL-DB nehmen, welche über eine DB-eigene Sprache programmierbar ist. Oder die bleibst bei SQLite und schreibst dir in Python eine eigene Aggregat-Funktion (Link.

BTW: Was heißt denn "größere" Datenmenge". Solange alles in RAM passt kann man auch mit langen Listen arbeiten. Insbesonders dann, wenn man die Abfragen / Sortierung nur sporadisch macht bzw. braucht.

Gruß, noisefloor
Antworten