Array aus pdo Abfrage läuft nur einmal

Hi,

warum willst Du irgendwas mitteln? Du lässt die Datenbank doch hoffentlich über Dein jeweiliges Intervall rechnen (z.B. summieren). Ich würde das Raster immer noch abhängig vom Zeitraum machen.

LG
 
Ich kann die DB nicht Summieren lassen, da ja nur "aktive" Zeitpunkte in die db kommen.

Ich glaube es ist einfacher den Raster zu fixieren, und die Mittelwerte daran auszurichten.
 
Hi,

was für Mittelwerte? Warum kannst Du die DB nicht summieren lassen?
Wenn es morgens von 9-11 Uhr geregnet hat, dann trocken war und dann ab 19 Uhr wieder geschüttet hat, willst Du das doch auch so anzeigen. Wofür willst Du da Mittelwerte berechnen?

LG
 
Ich verstehe nicht wirklich, was du meinst.

Ich habe mich da an meinen mrtg- bzw. Mailgraph Graphen orientiert.

Wenn jemand z.B. den Graphen zwischen 23.2.09 und 27.2.09 sehen will habe ich theoretisch 10080 mögliche Datenpunkte. Jetzt vergleiche ich diese DPs mit den Werten der db. Wenn ich jetzt dieses Array an die Graphenfunktion übergebe, fragt er mich logischerweise ob es mir noch gut geht und verabschiedet sich anschließend in endlosem Rechnen. Ausserdem kann ich das ja gar nicht darstellen (Auflösung). Daher habe ich bei diesem Beispiel 10080/1440=7 => ich addiere sieben Regenwerte => / 7=> ergibt wieder eine Auflösung von 1440.

Alles andere würde den Graphen verzerreren (nur aktive übergeben) oder das System ins Nirvana schicken.
 
Hi,

Wenn ich jetzt dieses Array an die Graphenfunktion übergebe, fragt er mich logischerweise ob es mir noch gut geht und verabschiedet sich anschließend in endlosem Rechnen. Ausserdem kann ich das ja gar nicht darstellen (Auflösung).

Richtig, genau das meinte ich. Es sei denn, Du willst ein Plakat von hier bis Meppen kleben... ;)

Du gibst jetzt also eine Auflösung vor. Was ich meinte, ist, dass Du die Datenbank die jeweiligen Werte pro Intervall berechnen lassen solltest. Ob Du die nun summierst oder den Mittelwert nimmst, spielt dabei keine Rolle. MySQL kann beides.

Das einzige Problem dabei ist, die Datensätze nach ihrem Intervall zu gruppieren. Das lässt sich aber aus der Start- und Endzeit und der Auflösung leicht berechnen.

Code:
SELECT (messzeit - startzeit) * auflösung DIV (endzeit - startzeit) AS interval_nr,
   AVG(messwert) AS wert
   FROM messwerte 
   WHERE messzeit between startzeit AND endzeit 
   GROUP BY interval_nr 
   ORDER BY messzeit ASC

messzeit, startzeit und endzeit müssen dabei Unix-Timestamps sein (kannst Du ja gegebenenfalls umrechnen lassen). Probier die Abfrage mal aus. Ich habe natürlich keine sinnvollen Testdaten.

Dann erstellst Du Dir einfach ein leeres Array mit <auflösung> Elementen, durchläufst das Abfrageergebnis und sortierst die Werte entsprechend ihrer Intervallnummer ein:

PHP:
$points = range(0, $resolution - 1);
while($row = $result->fetch(PDO::FETCH_ASSOC)) {
   $points[$row['interval_nr']] = $row['wert'];
}

LG
 
Ich bin noch nicht ganz durch, aber diese Abfrage setzt doch vorraus, dass ich für jeden Zeitpunkt eine Zeile in der db habe. Ich habe das einmal so zusammengebaut, und das funktioniert soweit auch sehr gut. Eine Jahresabfrage dauert ca. 36 sek. und wird, wenn ich die Datensätzte schon in der db auf den Mittelwert (derzeit 4) sicher noch besser. Falls das über sql schneller ist, wäre das natürlich super. Derweil habe ich das nur mit einem Sensor probiert. Interresant wird es, wenn ich mehrere Berechne.

PHP:
$rain_result = $db_pdo->prepare("SELECT rain_date, rain_mm, rain_time FROM rain WHERE (rain_date >= '$in[year]-$in[month]-$in[day]' and rain_date <= '$out[year]-$out[month]-$out[day]' AND rain_place = 1) ORDER BY rain_date, rain_time");
$rain_result->execute();
$row = $rain_result->fetchAll(PDO::FETCH_ASSOC);


// Anzahl der Tage
$startdatum = mktime(0, 0, 0, $in[month], $in[day], $in[year]);
$enddatum = mktime(0, 0, 0, $out[month], $out[day], $out[year]);
$diff = $enddatum - $startdatum;
$mwfaktor_dp = round ($diff / 86400) * 4;

$dp_row = array();

// Aus DB in Array füllen
foreach ($row as $row2) {

    $dp_row[$row2[rain_date].$row2[rain_time]] = $row2[rain_mm];

}

$s = 1;
$mw_array = array();


for ($i = $startdatum; $i < $enddatum; $i += 60) {

    if ($s != $mwfaktor_dp) {
        $mw += $dp_row[date("Y-m-dH:i:s", $i)];
        $s++;
    }
    
    else {
        $mw /= $mwfaktor_dp;
        $s = 1;
        array_push ($mw_array, $mw);
        unset ($mw);
    } 
}
 
Hi,

Ich bin noch nicht ganz durch, aber diese Abfrage setzt doch vorraus, dass ich für jeden Zeitpunkt eine Zeile in der db habe.

Die Abfrage liefert Dir für jedes Intervall, in dem Datensätze vorhanden sind, den Mittelwert. Damit Du alle Punkte für Deine Plot-Funktion hast, wird das Ergebnis beim Auslesen in das leere Punkte-Array einsortiert.

Eine Jahresabfrage dauert ca. 36 sek.

Ja, das glaube ich Dir gerne. Abgesehen davon, dass Du erstmal alle Datensätze im Zeitraum durchlaufen musst, um das Array zu füllen, hat die anschliessende For-Schleife bei einem Zeitraum von einem Jahr ja auch über 500.000 Durchläufe. :eek:

Wenn Du eine Auflösung, also eine Anzahl Punkte, aus denen die Kurve gezeichnet werden soll, festlegst, liefert die Abfrage, die ich Dir gepostet habe, natürlich auch nur maximal so viele (vorberechnete) Datensätze. D.h. Du hast maximal $resolution Durchläufe.

LG
 
Bin da gerade am probieren, aber er macht mir das Array voll mit strings statt floats. Wie kann ich das umwandeln?

Code:
[0]=>   string(5) "0.018"
 
Hi,

meinst Du in meinem Beispielcodeschnipsel?

PHP:
while($row = $result->fetch(PDO::FETCH_ASSOC)) {
   $points[$row['interval_nr']] = floatval($row['wert']);
}

LG
 
Zurück