Durchschnittsberechnung aus Datenbankeinträgen läuft schief
Lars van der Meer
- datenbank
- php
Hallo,
ich habe folgendes Problem:
Ich möchte die über einen Zeitraum von mehreren Wochen verteilten durchschnittlichen wöchentlichen Arbeitsstunden in eine Datenbanktabelle schreiben und auch wieder auslesen lassen, und muss da irgendwo einen groben Denkfehler eingebaut haben...
So habe ich für die erste Woche 25 Wochenstunden, für die zweite Woche 19 Wochenstunden eingetragen, was ja eigentlich eine durchschnittliche Wochenstundenanzahl von 22 ergeben müsste... die Datenbank spuckt mir aber 12.5 Stunden aus...?
Ich habe versucht, hier allen das Leben ein wenig leichter zu machen, und den nachfolgenden Code entsprechend auf das [wie ich glaube] Problem reduziert... ...sollte ich dadurch wichtige Informationen vorenthalten, bitte um Hinweis!
Danke für ernstgemeinte Ratschläge.
LG, Lars.
Zum Code:
eingabe.php sieht aus wie folgt:
...IN DER DATENBANK:
Die Tabelle "Stundendaten" enthält als Primärschlüssel "woche", diese ist vom Typ bigint AUTO_INCREMENT - der Primärschlüssel ist also als einfache Durchnummerierung ausgeführt. "wochenstundenanzahl", "gesamtstundenanzahl" sind vom Typ int, "durchschnitt" vom Typ double.
...PHP:
$con = mysqli_connect(...);
$res = mysqli_query($con, "SELECT woche, gesamtstundenanzahl FROM Stundendaten ORDER BY woche DESC LIMIT 1");
while ($dsatz = mysqli_fetch_assoc($res)) {
if ($dsatz["woche"] === NULL) {
$dsatz["woche"] = 1;
}
if ($dsatz["gesamtstundenanzahl"] === NULL) {
$dsatz["gesamtstundenanzahl"] = 0;
}
$neue_gesamtstundenanzahl = $dsatz["gesamtstundenanzahl"] + $_POST["wochenstundenanzahl"];
$aktuelle_Woche = $dsatz["woche"];
$neuer_durchschnitt = $neue_gesamtstundenanzahl / $aktuelle_Woche;
}
mysqli_query($con, "INSERT INTO Stundendaten (wochenstundenanzahl, gesamtstundenanzahl, durchschnitt) VALUES ('".$_POST['wochenstundenanzahl']."', '$neue_gesamtstundenanzahl', '$neuer_durchschnitt') ");
(die Wochenstundenanzahl wird via Formular <input name="wochenstundenanzahl" type="number" /> gepostet)
auswertung.php sieht aus wie folgt:
$con = mysqli_connect(...);
$durchschnitt = mysqli_query($con, "SELECT woche, durchschnitt FROM Stundendaten ORDER BY woche DESC LIMIT 1");
while($dudsatz = mysqli_fetch_assoc($durchschnitt)) {
if ($dudsatz["woche"] === NULL) {
exit("<p>Es sind noch keine Einträge vorhanden.</p>");
}
echo "<h3>Durchschnittliche Arbeitszeit pro Woche seit Anfang 2016: " . $dudsatz["durchschnitt"] . " Stunden</h3>";
}
Hallo Lars van der Meer,
Du holst dir mit LIMIT 1
nur einen Datensatz, deine while-Schleife umfasst also nur einen einzigen Durchlauf.
Ohnehin kannst du das Berechnen des Durchschnittes auch der Datenbank überlassen. SELECT AVG(Spaltenname)
ist dein Freund.
Bis demnächst
Matthias
Hallo,
danke für die Antwort!
LIMIT 1 ist aber durchaus beabsichtigt, da ich ja nur den LETZTEN und damit aktuellen (ORDER BY woche DESC) Durchschnittswert ausgeben will... Das müsste meines Erachtens mit meinem Code auch funktionieren; - so werden mit $_POST["wochenstundenzahl"] die Stundenzahlen der aktuellen Woche eingetragen und diese dann zu dem in der Datenbank gespeicherten Datensatz "gesamtstundenanzahl" addiert:
$neue_gesamtstundenanzahl = $dsatz["gesamtstundenanzahl"] + $_POST["wochenstundenanzahl"];
Die Variable $neue_gesamtstundenanzahl wird wiederum als "gesamtstundenzahl" in der Datenbank hinterlegt und bei erneutem Aufrufen des Algorithmus abermals zu NEU eingegebenen Stunden addiert, usw.
Mit $aktuelle_Woche wird dann eben die aktuelle Woche ausgelesen (die via AUTO_INCREMENT automatisch inkrementiert wird), und der Durchschnitt wird dann mit $neuer_durchschnitt = $neue_gesamtstundenanzahl / $aktuelle_Woche; berechnet und auch in die Tabelle eingefügt.
Dies sähe beispielsweise aus wie folgt:
Es werden zwei Datensätze eingetragen:
erste Woche: 25 Wochenstunden, Primärschlüssel: 1 [AUTO_INCREMENT]
$neue_gesamtstundenanzahl = 0 + 25; $aktuelle_Woche = 1; $neuer_durchschnitt = 25 / 1 /* $neuer_durchschnitt SOLLTE ALSO DEN WERT 25 HABEN! */
mysqli_query($con, "INSERT INTO Stundendaten (... durchschnitt) VALUES (... '$neuer_durchschnitt') ");
zweite Woche: 19 Wochenstunden, Primärschlüssel: 2 [AUTO_INCREMENT]
$neue_gesamtstundenanzahl = 25 + 19; $aktuelle_Woche = 2; $neuer_durchschnitt = 44 / 2 /* $neuer_durchschnitt SOLLTE NUN ALSO DEN WERT 22 HABEN! */
mysqli_query($con, "INSERT INTO Stundendaten (... durchschnitt) VALUES (... '$neuer_durchschnitt') ");
...die Datenbank spuckt mir dagegen statt 22 den Wert 12.5 aus. ...Was läuft da falsch?
Hallo Lars van der Meer,
Du holst dir mit
LIMIT 1
nur einen Datensatz, deine while-Schleife umfasst also nur einen einzigen Durchlauf.Ohnehin kannst du das Berechnen des Durchschnittes auch der Datenbank überlassen.
SELECT AVG(Spaltenname)
ist dein Freund.Bis demnächst
MatthiasDas Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
Tach,
So habe ich für die erste Woche 25 Wochenstunden, für die zweite Woche 19 Wochenstunden eingetragen, was ja eigentlich eine durchschnittliche Wochenstundenanzahl von 22 ergeben müsste... die Datenbank spuckt mir aber 12.5 Stunden aus...?
das ergibt sich aus deinem Code nicht; ich würde vermuten, das die Datensätze in deiner Datenbank anders aussehen, als du glaubst.
<?php $con = mysqli_connect(...); $res = mysqli_query($con, "SELECT woche, gesamtstundenanzahl FROM Stundendaten ORDER BY woche DESC LIMIT 1"); while ($dsatz = mysqli_fetch_assoc($res)) { if ($dsatz["woche"] === NULL) { $dsatz["woche"] = 1; } if ($dsatz["gesamtstundenanzahl"] === NULL) { $dsatz["gesamtstundenanzahl"] = 0; } $neue_gesamtstundenanzahl = $dsatz["gesamtstundenanzahl"] + $_POST["wochenstundenanzahl"]; $aktuelle_Woche = $dsatz["woche"]; $neuer_durchschnitt = $neue_gesamtstundenanzahl / $aktuelle_Woche; } mysqli_query($con, "INSERT INTO Stundendaten (wochenstundenanzahl, gesamtstundenanzahl, durchschnitt) VALUES ('".$_POST['wochenstundenanzahl']."', '$neue_gesamtstundenanzahl', '$neuer_durchschnitt') ");
1. 2. und 4. in einer Abfrage zusammen sollte so aussehen:
SELECT COUNT(id) AS wochenanzahl, SUM(wochenstundenanzahl) AS wochenstundenanzahl_gesamt, AVG(wochenstundenanzahl) AS durchschnitt_wochenstundenanzahl FROM Stundendaten;
mfg
Woodfighter