In ener SQLLite-Datenbank wird immer dann ein neuer Datensatz eingetragen, wenn ein System seinen Zustand ändert, z.B. von Rüsten auf Fertigen oder von Fertigen auf Unterbrechen, von Unterbochen wieder auf Fertigen usw. Wie ich aus den Datensätzen, nachdem ich sie per SQL-Select aus der Datenbank zurückgeholt habe, quasi "zu Fuß" die daraus resultierenden Differenzen und Summen berechne, ist nicht die Frage, das ist die "konventionelle" Lösung. Die Frage ist, gäbe es ein SQL-Statement, dass es mir ermöglicht z.B. die Summe all der Zeiten zu ermitteln, die zwischen einem "Unterbrochen"-Status und dem darauffolgenden Zustand "Fertigen" liegen? Kann man mit SQL überhaupt Berechnungen zwischen den Datensätzen einer Ergebnismenge ausführen? Frank P.S. die Tabelle hat fogende ganz simple Struktur: Datum, Zeit, Status. Die möglichen Stati sind: - Aus - Rüsten (d.h. Einrichten für neuen Auftrag) - Rüsten unterbrochen (z.B. Probleme mit dem Materialdurchlauf) - Fertigen - Fertigen unterbrochen (z.B. Werkzeug muss gewechselt werden)
grundsätzlich geht das schon, zumindest bei dem MS-SQL. Ich würde da so ran gehen. select sum( datediff(minute, s1.zeitpunkt, ( select min(zeitpunkt) from status s2 where s2.zeitpunkt > s1.Zeitpunkt and s2.status = "Rüsten unterbrochen") ) ) from status s1 where s1.status = rüsten aber wie man schon sieht ist das ganze nicht schön, also ist die Datenbankstruktur nicht für solche abfrage geeignet. Eventuell über ein trigger nachdenken der bei einem Status wechsel in eine extra tabelle dir Zeiten einträgt.
Auf die Schnelle fallen mir da nur Subqueries ein. Etwa so in der Art:
1 | SELECT sum((SELECT t2.timestamp |
2 | FROM logtable t2 |
3 | WHERE t2.timestamp > t1.timestamp |
4 | AND t2.zustand = "Fertigen" |
5 | ORDER BY t2.timestamp ASC |
6 | LIMIT 1 |
7 | ) - t1.timestamp |
8 | ) |
9 | FROM logtable t1 |
10 | WHERE t1.zustand = "Unterbrochen" |
Dürfte allerdings fürchterlich ineffizient sein, insbesondere wenn die Tabelle etwas größer wird und die passenden Indizes fehlen. Eventuell ließe sich auch was mit einem JOIN machen, da will ich um die Uhrzeit aber nicht mehr drüber nachdenken :) Eine andere Variante wäre es, die Summierung nicht erst im Nachhinein zu machen, sondern gleich wenn die entsprechenden Zustände auftreten. Also so etwa: Zustand wechselt auf "Unterbrochen" --> Zeit merken Zustand wechselt auf "Fertigen" --> gemerkte Zeit vorhanden? wenn ja -> Differenz bilden summieren gemerkte Zeit löschen Du bräuchtest also noch ein oder zwei weitere Tabellen.
Die Variante mit dem Merken und gleich vollständig eintragen ist sicher in Bezug auf die Handhabbarkeit der Datensätze einfacher, hat aber andere Nachteile. a) im Client müssen Zustände bzw. Werte "gemerkt" werden. Die gehen aber bei einem Absturz oder Stromausfall (kommt nicht häufig vor, aber bei hunderten von Clients eben doch immer mal wieder) verloren b) um den zuvor angelegten Datensatz mit der Dauer zu vervollständigen, müssen Daten zurückgelesen bzw. geupdatet werden, was zusätzlichen Traffik verursacht ... Im Einzelfall auch kein Thema, aber durch die Multiplikation der vielen Clients schon ein Faktor Erschwerend kommt hinzu, dass die Clients nicht direkt an der Datenbank hängen, sondern über einen sog. Multiplexer, der dann den Flaschenhals bildet. Frank
Frank Esselbach schrieb: > um den zuvor angelegten Datensatz mit der Dauer zu vervollständigen, > müssen Daten zurückgelesen bzw. geupdatet werden, was zusätzlichen > Traffik verursacht nur wenn man es nicht richtig macht. In datenbanken werden auch oft stored procedure verwendet. Den übergibst du einfach den Zeitpunkt und den aktuellen statuts und die Prozedure erledit das ganze datenbank zeug innerhalb der DB. Davon bekommt der client nichts mit.
Nur damit du später keine Enttäuschung erlebst: SQLLite ist nicht gerade dafür gemacht "viele" Clients zu bedienen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.