SQLLite: Differenz zwischen zwei Datensätzen

OP (Firma: Q3) #1801693
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren