• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

SQL-Query Zeit zwischen Änderungen

Roin

Freier Denker

Registriert
22 Juli 2013
Beiträge
581
Hallo Leute.
Ich habe gerade eine kleine Denkblockade und glaube, dass meine Lösung für ein Problem von mir sehr ineffektiv ist und vielleicht hat hier ja jemand einen besseren Vorschlag.

Zu der Tabelle:
idtimepointmainvalue......
132017-07-18-15-00-0013.05
142017-07-18-15-00-0114.1
152017-07-18-15-00-0214.1
162017-07-18-15-00-0314.1
172017-07-18-15-00-0415.0


Soweit zu der Ausgangssituation.
Nun möchte ich den Startzeitpunkt, Endzeitpunkt und die Zeitdifferenz wissen, in denen der Wert sich nicht geändert hat.

Meine (mögliche) Lösung wäre:
[src=mysql]SELECT t1.timepointAS startpoint, t3.timepoint AS endpoint
FROM tbl AS t1
INNER JOIN tbl AS t2 ON t1.id = t2.id-1
INNER JOIN tbl AS t4 ON t2.mainvalue = t4.mainvalue
INNER JOIN tbl AS t3 ON t3.id = t4.id+1
WHERE t1.mainvalue <> t2.mainvalue AND
t3.mainvalue <> t4.mainvalue AND
t2.mainvalue = 14.1[/src]

Derzeit habe ich leider kein System zur Hand, mit dem ich das testen könnte (SQLFiddler will irgendwie nicht...) aber so ähnlich würde ich das zumindest versuchen zu lösen.
Da gibt es aber bestimmt was besseres, oder nicht?

--- [2017-07-18 16:00 CEST] Automatisch zusammengeführter Beitrag ---

https://www.w3schools.com/sql/trysql.asp?filename=trysql_op_in

Über diese Seite habe ich festgestellt, dass meine obere Query noch nicht ganz ausgereift ist. Es können noch Werte "dazwischenspringen" und demnach das Ergebnis beträchtlich verfälschen.

Testquery auf der Seite war:
[src=mysql]SELECT t1.`CustomerID` as id1, t2.`CustomerID` as id2, t3.`CustomerID` as id3, t4.`CustomerID` as id4, t1.`CustomerName` AS startpoint, t3.`CustomerName` AS endpoint, t1.Country, t2.Country, t3.Country, t4.Country
FROM `Customers` AS t1, `Customers` AS t2, `Customers` AS t4, `Customers` AS t3
WHERE t1.`CustomerID` = t2.`CustomerID`-1 AND t2.`Country` = t4.`Country` AND t3.`CustomerID` = t4.`CustomerID`+1 AND t2.CustomerID <> t3.CustomerID AND t1.CustomerID < t3.CustomerID AND t1.`Country` <> t2.`Country` AND t3.`Country` <> t4.`Country` AND t2.Country = "Mexico"[/src]
 
Zuletzt bearbeitet:

drfuture

Zeitreisender
Teammitglied

Registriert
14 Juli 2013
Beiträge
8.728
Ort
in der Zukunft
Ist die Liste länger? Oder nur diese Werte, also ein Start, ein Ende und Werte dazwischen?
Wenn mehrere, wie unterscheidet sich Vorgang 1 von 2, also wie erkennst du im Zweifel ob Anfang oder Ende m
Wenn es nur ein Start ist würde ich eine Liste *gültiger* Werte erstellen indem ich in einem select nur die ids ausgebe bei denen ein Countdown auf den Wert kleiner 2 ist. Dann im äußeren select ein where in(select...)

Am Handy ist es gerade etwas schlecht einen echten query zu bauen :coffee:

Ob das dann unter dem Strich Effektiver ist müsste man messen..
 

Roin

Freier Denker

Registriert
22 Juli 2013
Beiträge
581
  • Thread Starter Thread Starter
  • #3
Also ich habe eine Liste mit einigen Zehntausend Werten (gerne auch mal eine Millionen).
Und "mainvalue" ist beispielsweise ein Sensorinput oder Ähnliches. Und dann ist, auf das obrige Beispiel bezogen, alles i.O., was kleiner als 15 aber größer als 14 ist.
Also 15 > x > 14 ist als ok anzusehen. Alles andere als Fehler. Und nun möchte ich Beginn der "Störung" und Dauer der Störung ausgegeben haben.
Mit den Daten muss das ja möglich sein.
Aber irgendwie nicht so einfach...

Der zweite Teil meines ersten Posts gibt zum Beispiel auch Werte aus, die nicht in unmittelbarer nähe zueinander liegen. Da weiß ich aber auch nicht, wie ich das wegbekommen soll ...

Um die Auswertung allgemein aber zu vereinfachen, möchte ich mit meiner Query nur Beginn und Ende eines Wertes erhalten. Ob der Wert, der dann die Zwischenzeit eingestellt ist "ok" ist oder nicht soll dann die nachgelagerte Logik klären. So bleibe ich deutlich flexibler in der Anwendung.

Ich hatte gerade ja sogar noch ein GROUP im Kopf, allerdings passiert das ja nicht so, wie ich das möchte...
 

drfuture

Zeitreisender
Teammitglied

Registriert
14 Juli 2013
Beiträge
8.728
Ort
in der Zukunft
Hm wenn ich deine Aufgabenstellung richtig verstehe ist dann das Beispiel oben nicht etwas schlecht? - dann ist hier ja der Beginn + Ende die erste Zeile - sprich als Ergebnis dürftest du bei dem Beispiel oben nur genau ein Ergebnis bekommen?
 

Roin

Freier Denker

Registriert
22 Juli 2013
Beiträge
581
  • Thread Starter Thread Starter
  • #6
IDTimepointmainvalue
12017-07-19 21:42true
22017-07-19 21:43false
32017-07-19 21:44false
42017-07-19 21:46 (achtung!)false
52017-07-19 21:46false
62017-07-19 21:47true
72017-07-19 21:48true
82017-07-19 21:49true
92017-07-19 21:50false
102017-07-19 21:51false
112017-07-19 21:52true
122017-07-19 21:53true
132017-07-19 21:54false
142017-07-19 21:55false
152017-07-19 21:56false
162017-07-19 21:57true

Damit haben wir ein anderes Beispiel. Wie zu beachten ist, die Zeitpunkte sind nicht eindeutig zu den IDs. Es können auch mal mehrere Werte pro Zeitpunkt vorkommen oder auch mal einige Zeit lang kein Wert aufgenommen worden sein.

Output sollte etwa folgendes sein:
AnfangszeitpunktEndzeitpunktDauer (optional)
Status (optional)
2017-07-19 21:422017-07-19 21:421true
2017-07-19 21:432017-07-19 21:464false
2017-07-19 21:472017-07-19 21:493true
2017-07-19 21:502017-07-19 21:512false
2017-07-19 21:522017-07-19 21:532true
2017-07-19 21:542017-07-19 21:563false
2017-07-19 21:572017-07-19 21:571true

Dabei sei die erste und letzte Spalte optional (da keine Daten davor und keine Daten dahinter vorhanden sind).

Alternativ sollte die Query auch dahingehend erweitert werden, dass nur das letzte derartige Ergebnis ausgegeben wird (im Zweifel könnte man das aus dem Ergebnis-Array bestimmen).
Die dritte Spalte (Dauer) kann aus den bestimmten Daten sehr einfach errechnet werden - daher nur eine Option, diese anzugeben. Der Status (Spalte vier) ist ebenfalls optional aber es wäre schön, wenn man diesen dennoch ausgeben könnte.

Meine Querys sind leider noch falsch und ich bin mir noch nicht sicher, woran es liegt bzw. weiß nicht, wie ich diese Verbessern kann.

EDIT


Da hast du Recht. Das hört sich sehr ähnlich an. Das schaue ich mir grad Mal näher an. Scheint fast so, als ob ich das Beispiel umsonst erweitert habe :D
Dabei habe ich deinen Post schlichtweg überlesen :unknown:

EDIT2:
Das ist anscheinend genau das was ich suche. Allerdings muss ich zugeben, dass ich die Query nicht so wirklich verstehe. Kann mir die jemand noch einmal erklären?

[src=mysql]@lastSeq := if( t.action = @lastAction AND
t.postID = @lastPostID AND
t.postType = @lastPostType, @lastSeq, @lastSeq +1 ) as ActionSeq[/src]
Wenn die Bedingung, dass sich nichts geändert hat, erfüllt ist, dann nehme die bisherige Seq (lastSeq) sonst inkrementiere um eins.

[src=mysql]( select @lastAction := ' ',
@lastPostID := 0,
@lastPostType := ' ',
@lastSeq := 0 ) sqlVars[/src]
Erzeuge Werte - lastSeq = 0 - ... Sozusagen eine Initialisierung der Variablen

[src=mysql]@lastSeq := if(..., @lastSeq, @lastSeq +1 ) as ActionSeq,
@lastAction := t.action,
@lastPostID := t.postID,
@lastPostType := t.PostType[/src]
Passe bisherige Variablen an die neuen Werte der jeweiligen Zeile an.

[src=mysql]group by
PreQuery.postID,
PreQuery.ActionSeq,
PreQuery.PostType,
PreQuery.Action[/src]
Fasse alle Werte zusammen, die u.A. die gleiche ActionSeq haben --> Es hat sich in diesen Zeilen keiner der betrachteten Werte geändert.

Alles richtig verstanden? Oder habe ich da einen groben Fehler drin?

EDIT 3
Meine Query müsste dann in etwa so aussehen:
[src=mysql]select
PreQuery.mainvalue,
min( PreQuery.timepoint ) as Startzeitpunkt,
max( PreQuery.timepoint ) as Endzeitpunkt,
TIMESTAMPDIFF(SECOND, min( PreQuery.timepoint ), max( PreQuery.timepoint )) as Dauer,
count(*) as AnzahlWerte
from
( select
t.*,
@lastSeq := if( t.mainvalue = @lastMainvalue, @lastSeq, @lastSeq +1 ) as ActionSeq,
@lastMainvalue := t.mainvalue
from
t,
( select @lastMainvalue := ' ',
@lastSeq := 0 ) sqlVars
order by
t.timepoint ) PreQuery
group by
PreQuery.ActionSeq,
PreQuery.mainvalue
[/src]
http://sqlfiddle.com/#!9/c043f4/1
 
Zuletzt bearbeitet:
Oben