Ankündigung

Einklappen
Keine Ankündigung bisher.

Werte filtern und zusammen rechnen

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

  • Werte filtern und zusammen rechnen

    Hallo,

    ich habe eine DB-Tabelle in die täglich und minütlich mehrere Zahlen/Werte eingetragen werden:
    Jetzt möchte ich, täglich getrennt, die immer letzten Werte vor einer Zelle die "0" ist, zusammenzählen.
    Beispiel:
    Datum id wert1
    12.01.2018 1234 0
    12.01.2018 1235 1
    12.01.2018 1236 2
    12.01.2018 1237 3
    12.01.2018 1238 0
    12.01.2018 1239 1
    12.01.2018 1240 2
    12.01.2018 1241 0
    12.01.2018 1242 0
    12.01.2018 1243 0
    13.01.2018 1244 0
    13.01.2018 1245 1
    13.01.2018 1246 2
    13.01.2018 1247 0
    13.01.2018 1248 1
    13.01.2018 1249 2
    13.01.2018 1250 3
    13.01.2018 1251 0
    13.01.2018 1252 1
    Als Ergebnis, welche ich dann anzeigen möchte, hätte ich für den 12.01.2018 "5" und für den 13.01.2018 "6"
    Hat vielleicht jemand eine Idee wie ich dies realisieren könnte?
    Vielen Dank schon mal für eure Vorschläge.

    Sascha


  • #2
    ...was mir gerade noch eingefallen ist.
    Ich muss nicht wissen wie ich auf die Datenbank zugreifen kann, das ist nicht das Problem.
    Mein Problem ist, dass ich nicht weiß, wie ich die entsprechende Zeile filtern kann.

    Kommentar


    • #3
      Deine Spalte Datum enthält kein ISO-Datum. Verwende den richtigen Datentyp in der DB für diese Spalte, dann ist das einfach.

      Kommentar


      • #4
        Hallo,
        das oben war nur ein Beispiel. Sorry, in "Wirklichkeit" ist es "datumzeit" "2018-01-12 10:12:03"
        Ich kann die Werte auch abfragen und anzeigen, weiß halt nur nicht wie ich diese "bestimmten" Werte filtern kann...

        Kommentar


        • #5
          Code:
          SELECT datum, count(wert1) AS Anzahl WHERE datum BETWEEN "2018-01-12" AND  "2018-01-13"
          GROUP BY datum
          so in etwa, ist ungetestet.

          Kommentar


          • #6
            MOD: Verschoben von PHP-Einsteiger
            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


            • #7
              Gemäß Deiner Daten und Deiner Beschreibung kommt an beiden Tagen 5 raus. Siehe selbst:

              Code:
              test=# create table saschaw(datum date, id serial, wert1 int);
              CREATE TABLE
              test=*# alter sequence saschaw_id_seq  restart with 1234;
              ALTER SEQUENCE
              test=*# insert into saschaw (datum, wert1) values ('2018-01-12',0);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-12',1);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-12',2);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-12',3);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-12',0);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-12',1);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-12',2);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-12',0);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-12',0);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-12',0);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-13',0);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-13',1);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-13',2);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-13',0);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-13',1);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-13',2);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-13',3);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-13',0);
              INSERT 0 1
              test=*# insert into saschaw (datum, wert1) values ('2018-01-13',1);
              INSERT 0 1
              test=*# select * from saschaw;
                 datum    |  id  | wert1
              ------------+------+-------
               2018-01-12 | 1234 |     0
               2018-01-12 | 1235 |     1
               2018-01-12 | 1236 |     2
               2018-01-12 | 1237 |     3
               2018-01-12 | 1238 |     0
               2018-01-12 | 1239 |     1
               2018-01-12 | 1240 |     2
               2018-01-12 | 1241 |     0
               2018-01-12 | 1242 |     0
               2018-01-12 | 1243 |     0
               2018-01-13 | 1244 |     0
               2018-01-13 | 1245 |     1
               2018-01-13 | 1246 |     2
               2018-01-13 | 1247 |     0
               2018-01-13 | 1248 |     1
               2018-01-13 | 1249 |     2
               2018-01-13 | 1250 |     3
               2018-01-13 | 1251 |     0
               2018-01-13 | 1252 |     1
              (19 rows)
              
              test=*# select *, case when lead(wert1) over (partition by datum order by id) = 0 then wert1 else 0 end as val from saschaw;
                 datum    |  id  | wert1 | val
              ------------+------+-------+-----
               2018-01-12 | 1234 |     0 |   0
               2018-01-12 | 1235 |     1 |   0
               2018-01-12 | 1236 |     2 |   0
               2018-01-12 | 1237 |     3 |   3
               2018-01-12 | 1238 |     0 |   0
               2018-01-12 | 1239 |     1 |   0
               2018-01-12 | 1240 |     2 |   2
               2018-01-12 | 1241 |     0 |   0
               2018-01-12 | 1242 |     0 |   0
               2018-01-12 | 1243 |     0 |   0
               2018-01-13 | 1244 |     0 |   0
               2018-01-13 | 1245 |     1 |   0
               2018-01-13 | 1246 |     2 |   2
               2018-01-13 | 1247 |     0 |   0
               2018-01-13 | 1248 |     1 |   0
               2018-01-13 | 1249 |     2 |   0
               2018-01-13 | 1250 |     3 |   3
               2018-01-13 | 1251 |     0 |   0
               2018-01-13 | 1252 |     1 |   0
              (19 rows)
              
              test=*# select datum, sum(val) from (select *, case when lead(wert1) over (partition by datum order by id) = 0 then wert1 else 0 end as val from saschaw) foo group by datum order by datum;
                 datum    | sum
              ------------+-----
               2018-01-12 |   5
               2018-01-13 |   5
              (2 rows)
              
              test=*#
              Solltest Du mit einer Datenbank hantieren, die (noch) keine Window-Funktionen wie lead() kennt: Pech für Dich.
              PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

              Kommentar


              • #8
                Hallo,
                protestix: hab das mal so versucht und bekomme hier immer alle Einträge des Tages angezeigt, das ist nicht das was ich wollte...

                akretschmer: ich habe MySQL und glaube das die lead() kennt.
                Du hast genau das gemacht was ich wollte: liest die Daten aus, speicherst sie in val und lies sie dann von dort wieder aus.
                Ich verstehe aber nicht, wie ich die Abfrage übernehmen soll: select *, case when lead(wert1) over (partition by datum order by id) = 0 then wert1 else 0 end as val from saschaw;
                Ich habe es mal so probiert, aber da bekomme ich ne Fehlermeldung (ja, ich weiß, ist zusammengestückelt, aber ich bin ja noch am Anfang): $q_data = mysql_query("select *, case when lead(wert1) over (partition by datum order by id) = 0 then wert1 else 0 end as val from saschaw") or die(mysql_error());
                Kannst du mir vielleicht die einzelnen Punkte erkläre? Was bedeutet das Sternchen (*) hinter select? case when lead()? partition by datum order by id (muss hier ne KLammer drum, oder muss ich mir was von den beiden aussuchen)?
                Ich glaube ich bin so nah an einer Lösung und doch so weit weg....

                Kommentar


                • #9
                  Mit MySQL bist Du eher sehr weit weg. lead(spalte) ist eine Window-Funktion, die den nächsten Wert der angegebene Spalte liefert, und das over() spezifiziert das Window, im dem diese Funktion suchen soll, hier pro Tag (partition by datum) und sortiert nach der id (order by id). Mit dem case when ... schau ich dann noch, ob lead() nun 0 oder ungleich 0 ist und nehme entweder den Wert oder 0. Siehst Du ja in der vorletzten Abfrage, was da passiert. Again: MySQL kann das nicht.
                  PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                  Kommentar


                  • #10
                    mmh, verstehe ich nicht.
                    Ich dachte ich kann ein PHP-Script schreiben und aufrufen und damit auf die Datenbank zugreifen? Was bedeutet eine "Window-Funktion"? Verstehe ich das jetzt richtig: das was ich vorhabe, kann ich mit MySQL nicht erreichen?

                    Kommentar


                    • #11
                      Window-Funktionen in SQL sind eine ganze Gruppe von Auswertungsfunktionen, sie ermöglichen Abfragen wie gezeigt und weitere sehr coole Dinge. Das ist genormt in einem SQL-Standard und quasi alle Datenbanken können das auch seit Jahren (PostgreSQL z.B. seit Version 8.4, also seit Juli 2009). MySQL kann es - nicht.


                      PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                      Kommentar


                      • #12
                        mal als Überblick:

                        das sind die Funktionen: https://www.postgresql.org/docs/10/s...ns-window.html , wichtig ist dazu noch die Definition der Windows: https://www.postgresql.org/docs/10/s...NDOW-FUNCTIONS

                        Und vielleicht noch ein paar Tutorials dazu:

                        * http://www.postgresqltutorial.com/po...ndow-function/
                        * https://www.compose.com/articles/met...in-postgresql/
                        * http://tapoueh.org/blog/2013/08/unde...dow-functions/

                        wie gesagt, das sind sehr mächtige Funktionen, die es ermöglichen, in der DB selbst recht komplexe analytische Auswertungen und Berechnungen vorzunehmen. Oracle kann das, M$SQL, DB2, Informix und andere, und als OpenSource-DB PostgreSQL.


                        PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                        Kommentar


                        • #13
                          Zitat von saschaw Beitrag anzeigen
                          Verstehe ich das jetzt richtig: das was ich vorhabe, kann ich mit MySQL nicht erreichen?
                          Ich denke schon das so etwas mit Hilfe von User-Defined Variables per MySQL machbar sein könnte, wenn auch sehr mühevoll und alles andere als schön.
                          Konkret ich hab ein Problem dein obiges Beispiel zu verstehen wo da für den 12.01.2018 vor der letzten 0 eine 2 und 1 steht und das 5 ergeben soll ..



                          PHP-Klassen auf github

                          Kommentar


                          • #14
                            Zitat von saschaw Beitrag anzeigen
                            mmh, verstehe ich nicht.Was bedeutet eine "Window-Funktion"? Verstehe ich das jetzt richtig: das was ich vorhabe, kann ich mit MySQL nicht erreichen?
                            Window Funktions könnte man am ehesten mit Spreadsheet Funktionen vergleichen, über die kein Mensch groß nachdenkt. Einfach eine Funktion zusammennagelen, Zellbezüge kreuz und quer, relativ und absolut, kein Thema.
                            Windows Functions in Datenbank können das im Grunde auch und wenn man sich noch nie Gedanken gemacht hat, was Datenbanken und Spreadsheets im Wesen unterscheidet, fällt einem immer noch nichts auf. Windows Functions sind für Datenbanken quasi was besonderes, dem entsprechend kann es nicht jede Datenbank.
                            In Kurz:
                            Eine Datenbank kann bei normalem SQL nicht auf "vorige" und "nächste" Datensätze zugreifen, egal wie nah dran oder weit weg. Datenbanken arbeiten Mengen orientiert und wissen nichts von den Nachbarwerten (außer denen in der Zeile eines Datensatzes also Links und Rechts)

                            Diese Funktionserweiterungen erlauben nun innerhalb SQL eine bequeme Adressierung (quasi wie im Spreadsheet so ungefähr) und sie sorgen durch die tiefgehende Implementierung auch dafür, dass man meist enorme Geschwindigkeitsvorteile gegenüber allen Workarounds hat, die versuchen bestimmte Windows Functions nachzustellen.

                            Fazit, eine DB die das kann, spart einem eine Menge Arbeit und allen Nutzern Wartezeit. Als erstes könnte man Clientseitige Konstrukte wegwerfen / weglassen, die mangels dieser Erweiterung Daten "lokal" zu Fuß verarbeiten. Dieser Client Code kann mit einem aufgerüsteten SQL meist komplett entfallen.

                            Laber Schwatz, probier es mal aus, gibt einige Online Systeme, wo Du direkt im Web etwas Windows Funktion SQL ausprobieren kannst.
                            Dabei kannst Du direkt Dein Datenbeispiel oben nutzen und allen hier verlinken, dann kann man Dir sogar richtig helfen.
                            (Ich habe Deine ursprüngliche Frage auch nicht verstanden)

                            Kommentar


                            • #15
                              Perry Staltic lustig erklärt

                              Trifft es meiner Meining allerdings nicht vollständig. Aber hey: lustig erklärt!

                              Mengenorientiert: richtig, aber Mengen *können* sortiert sein. Daher haben sie auch einen N-ten Vorgänger und einem M-ten Nachfolger. Das kann per-table sein oder auch per-GROUP BY.

                              Ach egal. Wie Perry Staltic schon sagt: am besten einmal selber ansehen.
                              PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                              Kommentar

                              Lädt...
                              X