SQLLite: Differenz zwischen zwei Datensätzen

OP (Firma: Q3) #1801693
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)
Gast #1801730
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.
Gast #1801740
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.
OP (Firma: Q3) #1801878
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
Gast #1801972
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.