Zur Boardunity Forenstartseite

Zurück   Boardunity Ratgeber Forum » Technik » Programmierung und Datenbanken

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1  
Alt 14.11.2005, 12:41
Benutzerbild von MrNase
Mitglied
 
Registriert seit: 06.2003
Ort: /
Beiträge: 2.628

MySQL, Einträge nach Tagen/Monaten gruppieren


Also, ich habe ein kleines Wetterscript welches alle ~ 15 Minuten die aktuelle Temperatur meiner Heimatstadt in eine Datenbank einliest.

Nun möchte ich aber gerne ein Diagramm erstellen welches die Temperaturen im Jahresverlauf ausgibt und da stosse ich auf ein Problem:

Für jeden Tag habe ich rund (!) 96 Datensätze, alle tragen nen timestamp (via time() und sind also auf die Sekunde genau zu bestimmen allerdings finde ich keinen Ansatz wie ich den Tagesdurchschnitt berechnen kann also wie ich alle Eintrage des Tags X gruppieren kann damit ich die entsprechenden Werte für ein Diagramm habe.

Eigentlich müsste die Abfrage folgendes leisten:

Tag 1: alle Tageswerte addiert = X
X / Anzahl der Tageswerte von Tag 1 = Tagesdurchschnitt von Tag 1

Tag 2:
alle Tageswerte addiert = X
X / Anzahl der Tageswerte von Tag 2 = Tagesdurchschnitt von Tag 2



Datenbankstruktur schaut wie folgt aus:

id -> auto_increment
zeit -> int(11)
temperatur -> int(10)


So sollte das Diagramm später mal aussehen:

Code:

 ^
 |
 |
 |      2
 |      _   3 
 |  1  | |  _
 |  _  | | | |
_|_|_|_|_|_|_|___>
 |

 

  #2  
Alt 15.11.2005, 18:44
Benutzerbild von codethief
Visionär
 
Registriert seit: 09.2003
Beiträge: 803
Hol dir alle Datensätze aus der Datenbank und finde mit getdate() oder date() das Datum von jedem Datensatz heraus. Dann musst du alle Datensätze eines Tages in ein Array (ein Objekt wäre evtl. noch klüger) tun und kannst die Daten auswerten. Ausgewertete Daten von bereits vergangenen Tagen würde ich der Performance wegen in einer anderen MySQL Tabelle abspeichern. Ob du nun alte Temperaturwerte löschst, bleibt dir überlassen. Die Statistik ginge dadurch ja nicht verloren.

Ich hab dir mal den eine komplette Klassenlib dazu geschrieben. Mit DayTempAnalyser::getAverages() bekommst du alle Tage, sowohl vergangene als auch den aktuellen, in einem Array. Die Datenbankfunktionen musst du natürlich ggf. durch eine andere Datenbankschnittstelle (DBKlasse oder so) ersetzen.
DayTempAnalyser ist eine Schnittstelle zu deiner Statistik, Day repräsentiert einen noch nicht vollendeten oder noch nicht vollständig ausgewerteten Tag (mit einer vorläufigen Tagesdurchschnittstemperatur), DayAverage hingegen einen schon vergangenen Tag mit einem abgeschlossenen bzw. endgültigen Durchschnitt.

PHP-Code:
class DayTempAnalyser
{
    private static 
$dayaverages = array();
    
    
    public static function 
getAnalysedDays()
    {
        
$get_averages mysql_query("SELECT * FROM dayaverages ORDER BY `date`");
        
        
$analysed_days = array();
        
        while(
$day mysql_fetch_array($get_averages))
        {
            
$analysed_days[$day['date']] = new DayAverage($day['date']);
            
            
$analysed_days[$day['date']]->setAverage($day['average']);
        }
        
        return 
$analysed_days;
    }
    
    public static function 
analyseNewTemperatures()
    {
        
$get_temps mysql_query("SELECT * FROM temperatures");
        
        while(
$temp mysql_fetch_array($get_temps))
        {
            
$date date("d-m-Y"$temp['timestamp']);
            
            if(!isset(
$this->dayaverages[$date])
            {
                
$this->dayaverages[$date] = new Day($date);
            }
            
            
$this->dayaverages[$date]->addTemperature($temp['temperature']);
        }
        
        foreach(
$this->dayaverages as $day)
         {
             
$day->calculateAverage();
             
$day->save();
         }
    }
    
    
    public static function 
getAverages()
    {
        
self::analyseNewTemperatures();
        
        return 
array_merge($this->dayaveragesself::getAnalysedDays());
    }
    
    
    
    
    public static function 
deleteDay($date)
    {
        unset(
$this->dayaverages[$date]);
    }
}




class 
Day
{
    private 
$date "";
    private 
$temperatures = array();
    private 
$average 0;
    
    public function 
__construct($date)
    {
        
$this->date $date;
    }
    
    public function 
addTemperature($temp)
    {
        
$this->temperatures[] = $temp;
    }
    
    public function 
calculateAverage()
    {
        
$sum 0;
        
        foreach(
$this->temperatures as $temperature)
        {
            
$sum += $temperature;
        }
        
        
$this->average $sum count($this->temperatures);
    }
    
    public function 
getAverage()
    {
        return 
$this->average;
    }
    
    public function 
save()
    {
if(
$this->date == date("d-m-Y")) // Durchschnitte vom aktuellen Tag können sich noch ändern, deshalb noch nicht speichern.
        
{
            return 
false;
        }
        else
        {
            
mysql_query("INSERT INTO dayaverages (`date`, average) VALUES ('".$this->date."', '".$this->average."')");
            
            
$date_exp explode("-"$this->date);
            
$day_start mktime(000, (int) $date_exp[1], (int) $date_exp[0], $date_exp[2]);
            
$day_end mktime(245959, (int) $date_exp[1], (int) $date_exp[0], $date_exp[2]);
            
            
// ausgewertete Temperaturen löschen
            
mysql_query("DELETE FROM temperatures WHERE `timestamp` >= ".$day_start." AND `timestamp` <= ".$day_end);
            
            
DayTempAnalyser::deleteDay($this->date);
        }
    }
}


class 
DayAverage extends Day
{
    private function 
addTemperature($temp) { }
    private function 
calculateAverage() { }
    private function 
save() { }
    
    public function 
setAverage($average)
    {
        
$this->average $average;
    }

Du könntest natürlich auch noch entsprechende Methoden bauen, um neue Temperaturen in die Datenbank einzufügen und evtl. sogar eine Methode, die dir basierend auf dem Array von DayTempAnalyser::getAverages(), ein fertiges Diagramm baut. Du könntest sogar soweit gehen und den Durchschnitt eines Monats oder eines ganzen Jahrs mit der Lib berechnen oder Höchst- und eine Niedrigsttemperaturen einbauen.

Die Datenbank für die Lib müsste folgendermaßen aussehen:

temperatures
- timestamp INT
- temperature FLOAT

dayaverages
- date VARCHAR(10) - im Format d-m-Y (kannst natürlich auch einen anderen Datentyp nehmen, du musst nur den Code entsprechend anpassen - VARCHAR war für mich jetzt am leichtesten, weil ich mit dem DATE Datentyp nur wenig Erfahrung habe)
- average FLOAT

Du kannst natürlich noch weitere Felder hinzufügen, wie du lustig bist.

Und achja - ich hab die Lib nicht getestet, also es könnten noch Bugs drin sein.


codethief.

  #3  
Alt 16.11.2005, 08:26
Benutzerbild von TRS
TRS TRS ist offline
Mitglied
 
Registriert seit: 02.2003
Ort: Berlin
Beiträge: 993
Theorie: Die Funktion FROM_UNIXTIME(unix_timestamp,format) in Kombination mit groupby sollten dies ermöglichen.

Antwort


Stichworte
-

Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Und-Suche mit MySQL exe Programmierung und Datenbanken 2 02.06.2005 12:43
Lohnt sich ein Umstieg von mySQL 3.x auf 4.1? Gérome Webspace, Webserver, Domains 2 07.05.2005 11:43
Einträge von Heute aus einer MySQL DB auslesen. Daniel Richter Programmierung und Datenbanken 10 08.11.2004 17:57
PHP & MySQL: Lizenzkonflikte wurden gelöst Michael Przybyla Boardunity-Talk 5 06.04.2004 20:57
forenentwicklung und die neuen mysql lizenzen Björn Entwicklung und Konzeption sozialer Software 4 12.11.2003 17:33






1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24