SQL Command / Uhrzeiten summieren

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von Animal2k.

    SQL Command / Uhrzeiten summieren

    Hallo zusammen
    ich häng gerade bei einer SELECT Abfrage und finde in keinem Forum etwas :(

    Ich habe eine Access DB wo 5 Columns sind, in einem Column sind Uhrzeiten(eigentlich ja Sekunden 00:00:25) die würde ich gerne summieren, nur leider steht hierbei auch eine Datum an erster stelle.
    Sprich:

    Columnname(Sekunden)
    01.01.1900 00:00:23
    01.01.1900 00:00:24
    01.01.1900 00:00:53
    01.01.1900 00:00:12

    Ich häng total an der SUM Funktion das er mir nur die Uhrzeit summiert und das Datum weglässt


    VB.NET-Quellcode

    1. da = New OleDbDataAdapter("SELECT Name, Vorname, sum(Sekunden) AS Sekunden 'ich weiss hier rechnet er das Datum auch als PLUS, ergo kommt Müll am Ende
    2. WHERE Produktionstag = #" & Format$(sDatum, "yyyy-MM-dd") & "#
    3. GROUP BY Name, Vorname", MyConn)


    Wie bekomm ich das hin das er mir in der Column "Sekunden" nur die HH:mm:ss rechnet und das Datum ignoriert

    Danke euch :thumbsup:

    Gockel schrieb:

    Dim Beginn, Ende, Bereich As Integer

    Ist der Access-interne Nullpunkt des Datums.
    Eigentlich müsste der Datentyp Timespan sein, aber ich glaube, Access unterstützt das nicht.

    Die Zeiten addieren müsste gehen, indem du deren Double-Werte addierst und in Datum zurück konvertierst

    Visual Basic-Quellcode

    1. TimespanSum = CDate(CDbl(Timestamp1) + CDbl(Timestamp2))

    Könnte analog auch direkt in Access-SQL funktionieren.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    du kannst die Sekunden herausziehen aus dem DateTime
    das Summieren könnte so aussehen

    das Feld myTime ist in der Tabelle als DateTime definiert
    31.07.2020 12:30:16
    etc...

    VB.NET-Quellcode

    1. Dim sSql As String = "SELECT Sum(Format([myTime],'ss')) AS Sekunden, Kunden3.Firma "
    2. sSql &= "FROM(Kunden3) "
    3. sSql &= "GROUP BY Kunden3.Firma "
    4. sSql &= "HAVING (((Kunden3.Firma)='Kasi'));"


    es wird auch korrekt summiert, ist aber ein ziemliches 'gefrickel'

    besser wie EDR in Post#2 sagte als INT, selbst wenn du ein zusätzliches Feld anlegen musst

    Animal2k schrieb:

    Wenn ich das Access Feld auf Int stelle kann ich natürlich 00:00:23 nicht mehr einfügen weil er ja keinen Doppelpunkt mag
    Das ist richtig. Warum auch sollte man 00:00:23 einfügen wollen, anstatt schlicht 23?

    Animal2k schrieb:

    Jetzt muss ich die Sekunden nur umrechnen damit ich wieder den Format wert von HH:mm:ss habe
    Und warum brauchst du den Format wert (was immer das sein mag) von HH:mm:ss?
    23 Sekunden sind 23 Sekunden - in Zahlen: 23.
    Das ist doch ganz einfach, odr?

    Animal2k schrieb:

    Columnname(Sekunden)
    01.01.1900 00:00:23
    01.01.1900 00:00:24
    01.01.1900 00:00:53
    01.01.1900 00:00:12


    Die Zeiten unterliegen starken Schwankungen und näheren sich teilweise dem Übergang zur Minute recht nah an. Die aktuelle Lösung mit dem summieren des Sekundenanteils basiert aber darauf, dass dieser break even point nie erreicht wird. Diesen Fehler zu Debuggen ist schon nicht ganz trivial, den Fehler im Ergebnis allerdings zu bemerken ist - ausreichend große Datengrundlage vorausgesetzt - fast unmöglich.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ChristianT.“ ()

    ChristianT. schrieb:

    Die aktuelle Lösung mit dem summieren des Sekundenanteils basiert aber darauf, dass dieser break even point nie erreicht wird.
    Das ist extrem schlampig programmiert, nur mit den Sekundenanteilen einer Zeitspanne zu rechnen.
    Ich hatte dir in Post #4 die korrekte Summenermittlung gepostet.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    petaod schrieb:

    Das ist extrem schlampig programmiert, nur mit den Sekundenanteilen einer Zeitspanne zu rechnen.


    Die Schlampigkeit fängt aber schon beim Speichern der Daten an, da diese eben nicht als Zeitspanne , sondern als Datum, vorliegen.

    petaod schrieb:

    Ich hatte dir in Post #4 die korrekte Summenermittlung gepostet.


    Hast du dem TE gepostet, nicht mir ;)
    Ich wollte ihm nur eine schwäche - seines anscheinend gewählten Lösungsweges - aufzeigen. Das dein Weg prinzipiell der besserer ist, ist natürlich klar.

    [line]​[/line]

    SQL-Abfrage

    1. SELECT Sum((Format([myTime],'mm')*60+Format([myTime],'ss'))) AS Sekunden, Kunden3.Firma
    2. FROM(Kunden3)
    3. GROUP BY Kunden3.Firma
    4. HAVING (((Kunden3.Firma)='Kasi'));


    Sowas wäre eventuell denkbar. Hierbei müsste man äquivalent zu Format([myTime],'mm')*60 alle Bestandteile des Datums in Sekunden umrechen und könnte dies dann summieren.
    habe nochmals über DataTime Feld nachgelesen und für MS-Access(2007 und >) kannst
    du DatePart verwenden

    siehe hier... support.microsoft.com/en-us/of…05-4e5a-8905-6001372223fa

    also kannst du SQL so schreiben

    VB.NET-Quellcode

    1. 'Dim sSql As String = "SELECT Sum(Format([myTime],'ss')) AS Sekunden, Kunden3.Firma "
    2. Dim sSql As String = "SELECT Sum(DatePart('s',[myTime])) AS Sekunden, Kunden3.Firma "
    3. sSql &= "FROM(Kunden3) "
    4. sSql &= "GROUP BY Kunden3.Firma "
    5. sSql &= "HAVING (((Kunden3.Firma)='Kasi'));"

    ChristianT. schrieb:

    Die Schlampigkeit fängt aber schon beim Speichern der Daten an, da diese eben nicht als Zeitspanne , sondern als Datum, vorliegen.
    Da Access kein Timespan kennt, ist das aber eine häufig verbreitete Methode, eine Zeitspanne als Datum zu speichern.
    Wenn man weiß, wie Access ein Datum codiert, ist das auch zielführend.
    Ein Datum ist die Zeitspanne seit 1.1.1900, gespeichert als Double in Tagen.

    Kasi schrieb:

    für MS-Access(2007 und >) kannst
    du DatePart verwenden
    Damit hast du wieder nur den Sekundenwert und vernachlässigst die Minuten und Stunden.
    Korrekt wäre, die DateDiff-Funktion zu verwenden, um die Differenz zum 1.1.1900 zu berechnen.
    also

    SQL-Abfrage

    1. DateDiff('s', #1/1/1900#, myTimestamp)

    Beispiel: techonthenet.com/access/functions/date/datediff.php
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Wie (in post#2) gesagt: IMO das wirklich einfachste ist, Sekunden als Zahl zu behandeln. Ist man mit ganzen Sekunden zufrieden, als int, sonst eben float.
    Zahlen kann man summieren und noch sonstwas für mathem. Operationen drauf ausführen (Durchschnitt, Min, Max), wo man bei Timespan oder gar Date sich einen Hirnkrampf einfängt.
    Das Umrechnen Double<->Timespan kann man dann in .Net abhandeln - die Timespan-Struktur hat ja Methoden dafür.

    (Nützt natürlich nix, das zu wissen, wenn man die Db vorgesetzt bekommt und nicht korrigieren darf.)

    /my 5 ct

    petaod schrieb:

    Damit hast du wieder nur den Sekundenwert und vernachlässigst die Minuten und Stunden.
    Korrekt wäre, die DateDiff-Funktion zu verwenden, um die Differenz zum 1.1.1900 zu berechnen.
    also

    SQL-Abfrage

    1. DateDiff('s', #1/1/1900#, myTimestamp)

    Beispiel: techonthenet.com/access/functions/date/datediff.php


    er will ja nur sekunden summieren, vielleicht sollte der TE erklären warum es nur um sekunden geht

    Kasi schrieb:

    er will ja nur sekunden summieren
    Ich gehe davon aus, dass er auch Sekundenwerte summieren will, die mehr als eine Minute andauern.
    70 Sekunden steht in der DB als ​01.01.1900 00:01:10.
    Nach der DatePart-Methode ziehst du da nur die 10 raus.
    Nach der DateDiff-Methode kriegst du die 70.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Morgen die Herren
    Danke für eure großes Feedback

    Die Datenbank hat jetzt aktuell kein Datum mehr in der Spalte, nur noch 00:01:23

    Wenn ich dieses mit der Datdiff Methode summiere erhalte ich aber auch die richtigen Werte

    VB.NET-Quellcode

    1. BsSql = "SELECT Bandabschnitt, Bandstopp, Takt, Sum(DatePart('s',[Sekunden])) AS Sekunden FROM Bandstopp
    2. WHERE Produktionstag = #" & Format$(sDatum, "yyyy-MM-dd") & "#
    3. GROUP BY Bandabschnitt, Bandstopp, Takt"


    also in der Anzeige(Diagramm) komm ich immer auf die richtigen Werte, da ja das Datediff nur die Sekunden zurückgibt.
    Ich habe also bei 1 Minute 10 dann 70 Sekunden, wenn ich das wieder mit Format (HH.mm:ss) ins Diagramm zurück gebe steht im Balken auch 00:01.10 Sekunden