Ankündigung

Einklappen
Keine Ankündigung bisher.

MySQL-Abfrage in Array prüfen ob gleicher Wert bereits vorhanden

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • #16
    Mal was zum spielen mit den vorhanden Daten...

    PHP-Code:
    <?php
    $sqlCreate 
    = <<<ENDSQL
    CREATE TABLE zeiten (id INTEGER PRIMARY KEY, datum TEXT, soll TEXT, ist TEXT);
    INSERT INTO zeiten (datum, soll, ist) VALUES
    ("10.07.2017", "5:00", "2:34"),
    ("11.07.2017", "5:00", "5:35"),
    ("12.07.2017", "5:00", "4:57"),
    ("10.07.2017", "5:00", "1:30")
    ENDSQL;
    $memDB = new PDO('sqlite::memory:');
    $memDB->setAttribute(PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION);
    $memDB->exec($sqlCreate);
    $result $memDB->prepare('
        SELECT datum, soll,
                SUM(ist)-
                ((SUBSTR(soll,0,INSTR(soll, ":"))*60) +
                (SUBSTR(soll, INSTR(soll, ":")+1, LENGTH(soll))))
                AS differenz,
                ABS(SUM(ist)/60)|| ":" || SUBSTR( "00" || (SUM(ist)- ABS(SUM(ist)/60)*60), -2, 2)
                as ist
        FROM
        (SELECT  datum,
                soll,
                (SUBSTR(ist,0,INSTR(ist, ":"))*60) +
                (SUBSTR(ist, INSTR(ist, ":")+1, LENGTH(ist)))
                AS ist
        FROM zeiten
        ORDER BY datum)
        GROUP BY datum
        '
    );
    $result -> execute();
    $myResult $result->fetchAll(PDO::FETCH_CLASS);

    print (
    '<pre>');
    print_r($myResult);
    print (
    '</pre>');
    Code:
    Array
    (
        [0] => stdClass Object
            (
                [datum] => 10.07.2017
                [soll] => 5:00
                [differenz] => -56
                [ist] => 4:04
            )
    
        [1] => stdClass Object
            (
                [datum] => 11.07.2017
                [soll] => 5:00
                [differenz] => 35
                [ist] => 5:35
            )
    
        [2] => stdClass Object
            (
                [datum] => 12.07.2017
                [soll] => 5:00
                [differenz] => -3
                [ist] => 4:57
            )
    
    )
    Wobei es wirklich besser ist das Datum im Typ date zu speichern , sonst geht die Sortierung schnell in die Hose....

    Kommentar


    • #17
      Zitat von protestix Beitrag anzeigen
      Wenn du mit Datumswerten arbeitest, dann bleibe doch einfach dabei. Eine Konvertierung, ich nehme mal an darum handelt es sich hier, zu einem Unix-Timestamp ist an keiner Stelle notwendig.

      Du scheinst aber die Daten nicht im Typ date zu speichern, denn dann wäre das Format 2017-12-31 und nicht 31.12..2017.

      Die Konvertierung nimmt man dann vor wenn man die Daten ausgeben will, so dass jeder Benutzer, die für sein Land übliche Darstellung erhält, meist dann in PHP.

      Ja wie gesagt, ich werde das noch so ändern, dass ich den Type-Date verwende anstatt einen Strings. Natürlich macht es keinen Sinn nochmal einen UNIX-Timestamp zu verwenden. Jedoch brauche ich etwas UNIQUES, um die gruppierten Daten nach dem Datum zu sortieren, und am besten so, dass sie in der richtigen Zeitreihenfolge sind. Deshalb habe ich mit den Gedanken gespielt, dass ich den TIMESTAMP temporär mit der Abfrage erstelle und danach sortiere.

      €:

      Zitat von kaminbausatz Beitrag anzeigen
      Mal was zum spielen mit den vorhanden Daten...

      [PHP]
      <?php
      $sqlCreate = <<<ENDSQL
      CREATE TABLE zeiten (id INTEGER PRIMARY KEY, datum TEXT, soll TEXT, ist TEXT);
      INSERT INTO zeiten (datum, soll, ist) VALUES
      ("10.07.2017", "5:00", "2:34"),
      ("11.07.2017", "5:00", "5:35"),
      [...]
      Danke für den Code! Ich hab meine Abfrage nochmal optimiert.

      Meine Tabelle beschränkt sich jetzt auf die Felder
      ID DATUM SOLL IST
      Die ganzen anderen Felder wie
      • ist_gesamt_tag
      • differenz_gesamt_tag
      • timestamp_eintrag
      erstelle ich bei der Abfrage. Vorteil: Alle gleichen Tage mit gleichen Soll-Zeiten werden zusammengefasst. Rest wird getrennt.
      Also habe ich alle meine Kriterien erfüllt weshalb ich den Thread gestartet habe!

      Bleibt nur noch die Aufgabe mit die Einträge mit dem gleichen Datum in richtiger Reihenfolge sortieren, aber da wird mir noch was einfallen.

      Nochmal ein fettes Dankeschön an alle, echt ne tolle Comminuty!

      Gruß

      Kommentar


      • #18
        PasiB

        Im Grunde ist Dein Datenbank Design etwas daneben.

        Du brauchst eine Tabelle mit DATUM und SOLL
        und eine zweite mit DATUM und IST.

        Kommentar


        • #19
          Zitat von kaminbausatz Beitrag anzeigen
          PasiB

          Im Grunde ist Dein Datenbank Design etwas daneben.

          Du brauchst eine Tabelle mit DATUM und SOLL
          und eine zweite mit DATUM und IST.
          Okay, hm.

          Kannst du mir vielleicht sagen warum das in besser ist? Dann kann ich in meinem Fall nochmal darüber nachdenken.


          Gruß

          Kommentar


          • #20
            Ja, bau Dir folgende 2 Tabellen:

            Code:
            CREATE TABLE sollzeiten ( datum TEXT, sollzeit INTEGER );
            INSERT INTO sollzeiten ( datum, sollzeit ) VALUES
            ("2017-07-10", "300"),
            ("2017-07-11", "300"),
            ("2017-07-12", "300");
            
            CREATE TABLE istzeiten ( datum TEXT, istzeit INTEGER );
            INSERT INTO istzeiten ( datum, istzeit ) VALUES
            ("2017-07-10", "154"),
            ("2017-07-10", "90"),
            ("2017-07-11", "335"),
            ("2017-07-12", "297");
            Und folgende Abfrage

            Code:
            SELECT  
                    sollzeiten.datum,
                    SUM(istzeiten.istzeit) AS ist ,
                    SUM(istzeiten.istzeit) - sollzeiten.sollzeit AS differenz
            
                    FROM istzeiten
            
            JOIN sollzeiten ON istzeiten.datum = sollzeiten.datum
            
            GROUP BY sollzeiten.datum;
            Du kannst auch mal http://sqlfiddle.com/#!9/4dda08/1 ausprobieren, dann erkennst Du sofort was ich meine...

            Kommentar


            • #21
              kaminbausatz : Der Ansatz unterliegt einigen Einschränkungen. So muß für jedes Datum mit Istzeit auch ein Datum mit Sollzeit vorliegen und es dürfen nicht mehrere Sollzeiten pro Datum vorliegen.

              Alternativ: Eine Tabelle, und als Konvention werden die Sollzeiten als negative Minuten eingetragen. Damit wird die Übung zum Kinderspiel...

              Kommentar


              • #22
                Zitat von jspit Beitrag anzeigen
                kaminbausatz : Der Ansatz unterliegt einigen Einschränkungen. So muß für jedes Datum mit Istzeit auch ein Datum mit Sollzeit vorliegen und es dürfen nicht mehrere Sollzeiten pro Datum vorliegen.

                Alternativ: Eine Tabelle, und als Konvention werden die Sollzeiten als negative Minuten eingetragen. Damit wird die Übung zum Kinderspiel...
                Das verzwickte an der Angelegenheit ist, dass er für jeden Tag nur eine Sollzeit hat die sich nicht aufaddiert und mehrere Istzeiten die sich aufaddieren. Wie es mit einer Tabelle geht ist in #16 dargestellt. Im Grunde ist es ja nichts anderes wie in der Projektzeiterfassung. Hier muss auch erst ein Projekt da sein um die Zeiten zu erfassen. Hier scheint es so zu sein, dass der Tag sinngemäß das Projekt darstellt.

                Kommentar


                • #23
                  Nur eine Tabelle zu pflegen vereinfacht die Handhabung. Statt der negativen Einträge ist wohl eine weitere Spalte mit einer Kennung besser:
                  Code:
                  DROP TABLE IF EXISTS `zeiten`;
                  CREATE TABLE zeiten ( datum DATE, zeit INTEGER, flag VARCHAR(11) );
                  INSERT INTO zeiten ( datum, zeit, flag ) VALUES
                  ("2017-07-10", "300", "s"),
                  ("2017-07-11", "300", "s"),
                  ("2017-07-12", "300", "s"),
                  ("2017-07-10", "154", "i"),
                  ("2017-07-10", "90", "i"),
                  ("2017-07-11", "335", "i"),
                  ("2017-07-12", "297", "i");
                  Die Abfrage geht dann so:
                  Code:
                  SELECT datum,
                  SUM(IF(flag = 's', zeit,0)) AS soll, 
                  SUM(IF(flag = 'i', zeit,0)) AS ist, 
                  SUM(IF(flag = 'i', zeit,-zeit)) as diff 
                  FROM zeiten
                  GROUP BY datum
                  ORDER BY datum;

                  Kommentar


                  • #24
                    jspit

                    Gute Lösung kommt in meine Sammlung, kann ich bestimmt irgendwann brauchen

                    Kommentar


                    • #25
                      Danke für die weiteren Anregungen! Leider ist beides für mich nicht von Nutzen.

                      Beim letzteren von jspit kann ich keine doppelten Sollzeiten speichern, bzw werden bei gleichen Sollzeiten diese addiert. Das ist genau das, was ich nicht möchte.

                      Und beim letzten von kaminbausatz ist es gar nicht möglich, mehrere Sollzeiten für einen Tag zu speichern. Da war das erste Beispiel schon genau das was ich mir vorgestellt hatte.

                      Aber wie gesagt, all meine Aufgaben bzw. Kriterien sind abgehakt. Und bleibe denke ich erstmal bei dem wie es momentan ist. Falls da irgendwelche Schwierigkeiten auftreten sollen muss ich mich dann wohl oder übel nochmal umorientieren, aber da hab ich ja jetzt genug Material und Snippets dieses zu verwirklichen.

                      Danke euch!

                      Kommentar


                      • #26
                        Zitat von PasiB Beitrag anzeigen
                        Beim letzteren von jspit kann ich keine doppelten Sollzeiten speichern, bzw werden bei gleichen Sollzeiten diese addiert. Das ist genau das, was ich nicht möchte.

                        Und beim letzten von kaminbausatz ist es gar nicht möglich, mehrere Sollzeiten für einen Tag zu speichern.
                        Was soll denn bitte gemacht werden wenn mehrere Sollzeiten für einen Tag vorliegen?

                        Kommentar


                        • #27
                          Zitat von jspit Beitrag anzeigen

                          Was soll denn bitte gemacht werden wenn mehrere Sollzeiten für einen Tag vorliegen?


                          Mal angenommen ich fange um 6:00 Uhr an, stemple dann um 9:38 aus weil ich einen Termin o.Ä habe.
                          Dann stemple ich um 12:04 wieder ein und gehe dann um 16:57 nach Hause.

                          Dann habe ich ja deswegen keine 16h Soll sondern immer noch 8h.

                          Natürlich sind das Ausnahmefälle und nicht die Regel. Aber aus diesem Grund möchte ich die Ist-Zeiten mit gleichen Sollzeiten zusammenfassen.
                          Die abweichenden Soll-Zeiten für einen Tag sollen dann extra behandelt werden. Also 8:00 und bsp. 0:00 Soll sollen nicht zusammengefasst werden. Wobei mir auf die schnelle kein Grund einfällt, warum man zwei unterschiedliche Soll-Zeiten für einen Tag haben könnte. Aber so wäre mein Lösungsansatz.
                          Am Ende des Tages hätte ich dann meine Ist-Zeit von

                          6:00 - 9:38, 12:04 - 16:57 | 8:00
                          17:06 - 18:09 | 0:00


                          Daran merkt man A) dass ich richtig bescheidene Arbeitszeiten habe , und B) dass das ganze nicht ganz so trivial ist wie ich es zu anfangs dachte.
                          Aber so macht es denke ich Sinn für den täglichen Gebrauch.

                          Kommentar


                          • #28
                            Ist-Zeit berechnen und mit Soll-Zeit abgleichen sind zwei in sich selbst unterschieldiche Themen. Einzig haben Sie gemein, das es jeweils einen (gemeinsamen) Tag (und User) betrifft.

                            Würde dir mal vorschlagen das du zuerst mal die Ist-Zeiten-Protokollierung komplett machst und dann im zweiten Schritt den Abgleich mit den Sollzeiten.

                            Und .. falls relevant.. Bedenke das die Nacht in der Zeitumstellung jeweils eine Stunde mehr bzw. weniger hat. Dh da hast du von 01:00 bis 03:00 (wenn Uhr zurückgestellt wird) drei Stunden statt nur zwei gearbeitet, falls du dein Tool auch mal für sowas verwenden willst.

                            Code:
                            user 
                            id  name
                            1   hans
                            Code:
                            times
                            id  user_id  date        from   to
                            1   1        2017-07-26  06:00  09:38
                            2   1        2017-07-26  12:04  16:67
                            3   1        2017-07-26  17:06  08:09
                            Mal so spontan (ev. datum noch normalisieren, bin gerade nicht sicher) .. Und dann mal darus die Ist-Arbeitszeit berechnen.

                            Wenn du das dann hast kannst du eine Soll-Tabelle je Tag/User machen und dann abgleichen.

                            EDIT:
                            An dieser Stelle auch der Hinweis das es sowas auch sicher schon fertig gibt.. Also wenn du das Rad nicht neu erfindne willst.. frag mal die Schmaschine deiner Wahl dazu.
                            The string "()()" is not palindrom but the String "())(" is.

                            Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                            PHP.de Wissenssammlung | Kein Support per PN

                            Kommentar


                            • #29
                              Ich hab seit #17 schon meine Lösung gefunden. Und komme damit schon gut klar, jedoch kommen zwischendrin immer mal wieder Beiträge dazu in denen man nochmal spekuliert und Diskutiert.



                              Gruß

                              Kommentar

                              Lädt...
                              X