Posts mit dem Label mysql werden angezeigt. Alle Posts anzeigen
Posts mit dem Label mysql werden angezeigt. Alle Posts anzeigen

Tutorial - Wetterdaten und Datenbanken - Teil 1 - Einleitung

Wetterdaten und Datenbanken 


Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch


Einleitung


Datenbanken eignen sich für die Ablage von Wetterdaten besonders gut. Diese wurden entwickelt, um große Datenmengen zu verwalten. Vereinfacht kann man sich Datenbanken wie eine Tabelle aus zB. Excel vorstellen. Oft enthalten Datenbanken mehrere solcher Tabellen, welche zudem miteinander verknüpft sein können.


Einige Vorteile


  • Schneller Zugriff
  • Filter / Sortierung
  • Berechnungen wie sum/min/max/avg
  • Datumsfunktionen
  • geringer Platzbedarf
  • komfortable Verwaltung


Tabellen


Hier ein Beispiel einer Tabelle:


MySQL Tabellen Inhalt angezeigt von phpMyAdmin



Für jede Spalte muss mindestens ein Name und Typ angegeben werden. Gewisse Typen verlangen zusätzliche Parameter wie z.B die maximale Grösse/Länge.


MySQL Tabellen Struktur angezeigt von phpMyAdmin


Speicherbedarf 


Gehen wir von einem 5 Minuten Speicherinterval aus., dann sind das 288 Datenzeilen pro Tag. Das sind pro Monat bereits 8640 und im Jahr schon über 105'000. Gehen wir von ca. 15 Spalten aus, sind das über 1.5 Millionen Einzelwerte pro Jahr. (So eine Tabelle mit Wetterdaten, belegt bei mir ca. 6 MByte im Jahr.)

Diese Datenmengen aufzunehmen, sollte für MySQL aber kein Problem darstellen. Die Zugriffszeiten hängen aber von der Abfrage selbst, sowie der Leistungsfähigkeit und Auslastung des Servers ab. 


Verwaltung:


Als Graphische Oberfläche dient uns das Tool phpMyAdmin. Es ist bei den meisten Providern vorinstalliert und erlaubt das einfache Verwalten von MySQL. Ansonsten bedient man eine Datenbank mit sogenannten sql-Befehlen. Dazu aber Später mehr.




Tutorial - Wetterdaten und Datenbanken - Teil 2 - Tabelle erstellen

Teil 2 - Tabelle erstellen


Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch


Die Wetterdaten werden in einer Tabelle gespeichert. Jede Zeile enthält Datum, Zeit und die Werte der Sensoren zum jeweiligen Zeitpunkt.

(Frühe Versionen dieses Tutorials enthielten noch die Spalte dateid. Diese wurde in einem Update entfernt.)




1. Neue Tabelle erzeugen


Zuerst in phpMyAdmin einloggen. Dann eine neue Tabelle erzeugen:




2. Spalten der Tabelle


Name, Typ und Länge wie im Bild ausfüllen und zusätzlich für die Spalte "datetime" PRIMARY aktivieren: 



3. Speichern


Jetzt "speichern" um die Tabelle anzulegen. Diese ist jetzt für das Eintragen von Daten vorbereitet.


Weiter mit Teil 3 - Tabelle füllen

Optional: Kurze Beschreibung der Spalten und Typen


Name: datetime
Typ: "datetime" für Datum und Zeit im Format "2013-11-25 00:00:00"
Verwendung:  Das Datum und die Zeit. Für diese Spalte aktivieren wir PRIMARY unter Index.

Name: temp, hum, pressure, etc.
Typ: "decimal" für Dezimalzahlen mit Kommastellen. Benötigt max. Länge inklusive Anzahl Kommastellen. (Bei Länge (5,1) wären also die Werte  -9999.9 bis 9999.9 erlaubt. Passen Sie diese gegebenenfalls an Ihre Bedürfnisse an. z.B: 2 Kommastellen (6,2) für 9999.99)
Verwendung: Die decimal Spalten nehmen die Wetterdaten auf.

Optimierung: (Besten Dank für den Tipp im Kommentar):
Die Wetterwerte könnte man auch in SMALLINT speichern (dann mit zb. 10 multiplizieren). Die Tabelle würde dann einiges weniger Speicherplatz belegen.

Tutorial - Wetterdaten und Datenbanken - Teil 3 - Tabelle füllen

Teil 3 - Tabelle mit Daten füllen

Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch

Unsere Tabelle enthält noch keine Daten. Es gibt nun diverse Möglichkeiten, unsere Wetterdaten in die Tabelle zu bekommen. Sehen wir uns einige Wege an.



Mit phpMyAdmin


Mit phpMyAdmin lassen sich Daten über ein Formular einfügen.

1. Einfügen öffnen und einen ersten Datensatz wie im Bild eingeben. Dann auf "OK" klicken.




2. Um den Datensatz anzusehen, "Anzeigen" wählen:







Achtung: Die Tabelle lässt keine doppelten Einträge in der Spalte "datetime" zu. (Die "datetime" jeweils ändern, um einen neuen Datensatz anzulegen)


Ein wenig SQL ?


SQL ist die "Sprache" der Datenbanken. phpMyAdmin bietet einen Bereich wo man sql-Befehle direkt ausführen kann. Wir sehen uns das mal an:

In phpMyAdmin "SQL" öffnen und folgenden Text in das Fenster schreiben/kopieren:


1. Zuerst unsere Tabelle auswählen ...

INSERT INTO wettertabelle


2. ... dann die Spaltennamen ...

(`datetime`,`temp`,`hum`,`pressure`) 


3. ... und die eigentlichen Werte. (in gleicher Reihenfolge wie die Spaltennamen):

VALUES
('2013-11-25 00:05:00','11.9','87','999.4')


Hier der sql-Befehl nochmals komplett:

INSERT INTO wettertabelle 
(`datetime`,`temp`,`hum`,`pressure`) 
VALUES
('2013-11-25 00:05:00','11.9','87','999.4')






4. Jetzt auf "Ok" klicken, und der Datensatz sollte unter "Anzeigen" zu sehen sein.




Jetzt mit PHP


1. Eine neue php Datei mit folgendem Inhalt erstellen. (z.B. eintragen.php).

2. Zuerst mit der Datenbank verbinden:

$link = mysqli_connect("Hostname", "Username", "Password", "DBname");
(Mit Ihren Zugangsdaten ersetzen)


3. Der $query weisen wir die sql-Befehle von vorhin zu:

$query = "

INSERT INTO wettertabelle
(`datetime`,`temp`,`hum`,`pressure`) 
VALUES
('2013-11-25 00:10:00','11.9','87','999.4')

";


4. $query noch ausführen:

mysqli_query($link,$query);



Nochmals die komplette php Datei:

<?php

//db verbindung
$link = mysqli_connect("Hostname", "Username", "Password", "DBname");


$query = "
INSERT INTO wettertabelle 
(`datetime`,`temp`,`hum`,`pressure`) 
VALUES
('2013-11-25 00:10:00','11.9','87','999.4')
";


mysqli_query($link,$query);

?>



5. Nun die erstellte php Datei auf den Server übertragen und im Browser öffnen. (Achtung: Die Datei erzeugt keinerlei Ausgabe)



6. Zur Kontrolle in phpMyAdmin unter "Anzeigen" nachschauen ob der Eintrag geglückt ist.



Weiter mit Teil 3.1 - Archiv importieren (wswin)



Tutorial - Wetterdaten und Datenbanken - Teil 3.1 - Tabelle mit Archiv füllen

Teil 3.1 - Tabelle mit Archivdaten füllen


Wetterdaten einzeln von Hand einzupflegen, mag teilweise nötig sein, ist aber nicht sehr aufregend. Mit ein wenig php, kann man aber ganze Archive, ohne großen Aufwand in eine Datenbank übertragen.

Als Beispiel dient hier eine (Monats-) Export Datei von WsWin.


Datenquelle: Exportdateien von WsWin


Hier ein Beispiel einer (Monats)Exportdatei von WsWin:


(Beachten: Die Datenzeilen beginnen in meiner Datei erst mit Zeile 4)

Die php Datei:


Beachte: Es gibt einige Methoden für diese Aufgabe. Der hier aufgezeigte Weg ist vermutlich nicht der optimalste und schnellste, aber m.M. nach einfach nachzuvollziehen und anzupassen. Für einen einmaligen Import großer Datenmengen ist Performance auch nicht unbedingt so wichtig.


1. Die Import Datei


Zuerst die WsWin Export Datei auf den Server laden. (z.B. EXP201311A.CSV)



2. Die php Datei


Wir erstellen zuerst ein php Script, welches den Inhalt unserer WsWin Datei mit echo anzeigt.
Eine php Datei mit folgendem Inhalt erstellen, und auf den Server laden:

(Die Variablen $dateiname und $startzeile an Ihre Exportdatei anpassen).

<?php

//Dateiname der Importdatei
$dateiname = "EXP201311A.CSV";

//Anzahl Anfang Zeilen überspringen
$startzeile = 4;


//Die Import Datei öffnen
if (($handle = fopen("$dateiname", "r")) !== FALSE) 
{

  //zeilenzähler auf 0
  $counter = 0;

  //Jede Zeile abarbeiten
  while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
  {

    //counter rauf
    $counter++;

    //die ersten zeilen überspringen
    if($counter >= $startzeile) 
    {

      //das echo (ausgabe)
      echo $data[0].", ".$data[1].", ".$data[3].", ".$data[10]. ", ".$data[11]."<br>\n";
   

    }
   
  }

  //Import Datei schliessen
  fclose($handle);
}
?>


Wird diese php Datei im Browser geöffnet, sollten Inhalte der Import Datei etwa so angezeigt werden:

Beachte: Datum/Zeit Format und evtl. falsche Spalten

Vermutlich werden aber noch nicht alle benötigten Felder richtig ausgegeben und das Datumformat stimmt auch nicht.


3. Die richtigen Felder ausgeben


Die Spaltennummern sind aber vermutlich nicht bei allen Benutzern gleich wie bei mir.
Im echo Teil des Scripts wird das array "$data" ausgegeben. Die Zahlen in den [] Klammern dahinter, entsprechen der Reihenfolge der Spalten in der Importdatei.

echo $data[0].", ". $data[1].", ".$data[3].", ".$data[10]. ", ".$data[11]."<br>\n";

(Das Datum ist bei mir in Spalte [0], Zeit in Spalte [1], Temperatur in Spalte [3] etc.)


4. Das Datum formatieren:


Für die Datenbank benötigen wir das Datum im Format "2013-11-25 00:00"

Wir zerlegen das Datum und die Zeit der Import Datei und bauen diese in den Variablen $d1 wieder zusammen.

$splitDate = explode(".", $data[0]);  //Das Datum zerlegen 
$splitTime = explode(":", $data[1]);  //Die Zeit zerlegen


//Das Datum für Spalte datetime (2013-11-25 00:00)
$d1 = $splitDate[2]."-".$splitDate[1]."-".$splitDate[0]." ".$splitTime[0].":".$splitTime[1];


Das echo entsprechend anpassen. Zuerst das Datum $d1, dann wieder die Werte der Spalten:

echo $d1.", ".$data[3].", ".$data[10]. ", ".$data[11]. "<br>\n";


Unsere php Datei sollte nun folgenden Inhalt haben:

<?php

//Dateiname der Importdatei
$dateiname = "EXP201311A.CSV";

//Anzahl Anfang Zeilen überspringen
$startzeile = 4;


//Die Import Datei öffnen
if (($handle = fopen("$dateiname", "r")) !== FALSE) 
{

  //zeilenzähler auf 0
  $counter = 0;

  //Jede Zeile abarbeiten
  while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
  {

    //zeilenzähler rauf
    $counter++;

    //erst ab dieser Zeile ausgeben
    if($counter >= $startzeile) 
    {

   
   // datum und Zeit zerlegen und neu zusammenbauen
   $splitDate = explode(".", $data[0]);
   $splitTime = explode(":", $data[1]);

   $d1 = $splitDate[2]."-".$splitDate[1]."-".$splitDate[0]." ".$splitTime[0].":".$splitTime[1] ;
   
   

     //das echo (ausgabe)
     echo $d1.", ".$data[3].", ".$data[10]. ", ".$data[11]."<br>\n";
   

    }
   
  }

//Import Datei schliessen
fclose($handle);
}
?>


5. Die Ausgabe kontrollieren:




Jetzt sieht die Sache schon besser aus.


6. Vom echo zum SQL-Insert


Statt die Daten nur auszugeben, wollen wir sie jetzt in die Datenbank Tabelle importieren. Zuerst die Datenbank Verbindung am Anfang des Scripts.

//db verbindung
$link = mysqli_connect("Hostname", "Username", "Password", "DBname");
(Mit Ihren Zugangsdaten ersetzen)


Wir erinnern uns an den SQL-Insert Befehl in Teil 3:

$query = "
INSERT INTO wettertabelle 
(`datetime`,`temp`,`hum`,`pressure`) 
VALUES
('2013-11-25 00:05:00','11.9','87','999.4')
";


Die Wetterdaten nach "VALUES" mit unseren Variablen (aus dem echo) ersetzen:

$query = "
INSERT INTO wettertabelle 
(`datetime`,`temp`,`hum`,`pressure`) 
VALUES
('$d1','$data[3]','$data[10]','$data[11]')
";

mysqli_query($link,$query);


7. Zusammenfassung:


Hier nochmals das ganze Script:

<?php

//Dateiname der Importdatei
$dateiname = "EXP201311A.CSV";

//Anzahl Anfang Zeilen überspringen
$startzeile = 4;


//db verbindung
$link = mysqli_connect("Hostname", "Username", "Password", "DBname");


//Die Import Datei öffnen
if (($handle = fopen("$dateiname", "r")) !== FALSE) 
{

  //zeilenzähler auf 0
  $counter = 0;

  //Jede Zeile abarbeiten
  while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
  {

    //counter rauf
    $counter++;

    //erst ab dieser Zeile ausgeben
    if($counter >= $startzeile) 
    {

   
   // datum und Zeit zerlegen und neu zusammenbauen
   $splitDate = explode(".", $data[0]);
   $splitTime = explode(":", $data[1]);
   
   $d1 = $splitDate[2]."-".$splitDate[1]."-".$splitDate[0]." ".$splitTime[0].":".$splitTime[1] ;
   


   //das echo (ausgabe)
     echo $d1.", ".$data[3].", ".$data[10]. ", ".$data[11]."<br>\n";
   
   
   //die db query
   $query = "
   INSERT INTO wettertabelle 
   (`datetime`,`temp`,`hum`,`pressure`) 
   VALUES
   ('$d1','$data[3]','$data[10]','$data[11]')
   ";
   
   //db query noch ausführen
   mysqli_query($link,$query);
   

    }
   
  }

//Import Datei schließen
fclose($handle);
}
?>

Wird diese Datei nun im Browser geöffnet, wird jede Zeile einzeln in die Datenbank importiert. Sie können die neuen Einträge in phpMyAdmin unter "Anzeigen" kontrollieren.

(Die echo Ausgabe können Sie auch entfernen, Sie wird für den Import nicht benötigt.)





(Optional) Mehrere Dateien Importieren


Je nach Umfang der Archive kann es komfortabel sein, mehrere WsWin Monatsdateien auf einmal zu importieren. Sie können dazu das php Script leicht ändern, um ein ganzes Verzeichnis abzuarbeiten.

Vorsicht: Dieses, für große Datenmengen nicht optimale Script, verursacht für einige Sekunden eine hohe Server Auslastung. (Da es jede Zeile einzeln importiert!) Ich würde daher, nicht mehr als ein Jahr auf einmal importieren.


1. Wir ändern zuerst die Variable $dateiname in $dateiordner:

Folgender Bereich ...
//Dateiname der Importdatei
$dateiname = "EXP201311A.CSV";

... ersetzen mit: (Verzeichnisname anpassen):
//Ordner mit Importdateien
$dateiordner = "importdateien";




2. Mit scandir wird neu das Verzeichnis ausgelesen und die Dateinamen im array "$allFiles" abgelegt. Und dann mittels einer foreach-Schleife jede Datei einzeln abgearbeitet:

Folgender Bereich ...
//Die Import Datei öffnen
if (($handle = fopen("$dateiname", "r")) !== FALSE) 
{

.... ersetzen mit:
//verzeichnis scannen und dateinamen in array speichern
$allFiles = scandir($dateiordner);

//die foreach schleife
foreach ($allFiles as $dateiname) { 
 
//jetzt wie bisher die Datei öffnen
if (($handle = fopen("$dateiordner/$dateiname", "r")) !== FALSE) 
{
(Klammern nicht vergessen!)



3. Dann noch am Ende des Scripts, die foreach Schleife mit } schließen:

Folgender Bereich ...
//Import Datei schliessen
fclose($handle);
}

... ersetzen mit:
//Import Datei schliessen
fclose($handle);
}
}



Weiter mit Teil 3.2 - Livedaten importieren (wswin)

Tutorial - Wetterdaten und Datenbanken - Teil 3.2 - Tabelle mit Livedaten füllen

Teil 3.2 - Tabelle mit Livedaten füllen


Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch


Diese Methode unterscheidet sich nur geringfügig vom Beispiel in Teil 3.1. Dieses sollte daher vor dieser Anleitung durchgespielt werden.

Möchte man die Tabelle mit unseren Wetterdaten aktuell halten, gibt es diverse Methoden. Hier sei nur eine erklärt.

Es ist anzumerken das die folgende Methode eine Software benötigt welche Dateien Zeitgesteuert über z.B. FTP übertragen kann. Zudem werden cronjobs benötigt.

Um ein möglichst kleines Transfervolumen erreichen zu können, sollte die Software zudem in der Lage sein, bei erfolgreicher Übertragung die Datei zu löschen.

Leider kann ich diesbezüglich keine Empfehlung abgegeben. Ich für meine Zwecke, habe ein kleines Tool programmiert, welches die oben genannten Aufgaben übernimmt. Evtl. kann ich diese Software später freigeben, falls sich hier keine alternative findet. (Kommentare dazu ?)



1. Voraussetzungen


1. Zeitgesteuerte Übertragung von Dateien

2. Cronjobs


2. Datenquelle


Als Datenquelle eignet sich ws_newdata.csv von WsWin im Besonderen. Durch die Verwendung von dieser Datei lassen sich auch Übertragungsfehler überbrücken. ws_newdata.csv wird ja von WsWin ständig mit den neusten Datenreihen gefüllt. Löscht man diese Datei, wird automatisch eine neue erstellt und wieder weiter aufgefüllt.


ws_newdata.csv von WsWin



(Es können aber auch benutzerdefinierte Dateien von WsWin verwendet werden.) 


3. Datei übertragen


Die Datei, hier ws_newdata.csv, wird auf den Server übertragen. Die Intervalle können Sie prinzipiell frei wählen, ich gehe hier von 5 Minuten aus. Da diese Datei immer grösser wird, empfiehlt es sich, diese nach einer erfolgreichen Übertragung zu löschen. Somit enthält die Datei immer nur die noch nicht übertragenen Zeilen.

Fällt die Übertragung einmal aus, Puffert WsWin die Zeilen in der ws_newdata.csv bis wieder eine erfolgreiche Übertragung zustande kommt.



4. Die Datei importieren


Wir verwenden das selbe Script wie in Teil 3.1. Speichern wir es in einer neuen php Datei erneut ab

In dieser neuen php Datei, müssen wir jedoch noch den Dateinamen (der zu importierenden Datei), die Startzeile und evtl. die Spaltennummern in der Query anpassen:


//Dateiname der Importdatei
$dateiname = "ws_newdata.csv";

//Anzahl Anfang Zeilen überspringen
$startzeile = 3;


Auch die Spaltennummern in der query auf die richtigen Werte überprüfen:
$query = "
INSERT INTO wettertabelle 
(`dateid`,`datetime`,`temp`,`hum`,`pressure`) 
VALUES
('$d1','$data[3]','$data[10]','$data[11]')
";

mysqli_query($link,$query);



5. Die Datei löschen (Optional)


Wir haben sichergestellt das die Tabelle keine doppelten Einträge aufnimmt. Dennoch sollten wir verhindern, dass importierte Dateien nicht noch einmal aufgerufen werden. Wir löschen also nach einem erfolgreichem Import die ws_newdata.csv

//Import Datei schließen
fclose($handle);
unlink('ws_newdata.csv');
?>


6. cronjob/crontab


Unsere neue php Importdatei, muss nun in Intervallen aufgerufen/geöffnet werden.
Wir erstellen daher einen Cronjob, welcher die vorhin erstellte .php Datei, in Intervallen aufruft. Dabei muss sichergestellt sein, das jede Datei importiert wird, bevor jeweils eine neue eintrifft. Wir überprüfen ja die Übertragung, aber nicht das eigentliche Eintragen. Ich führe daher meine Datei jede Minute aus.

Beachte: Die Erstellung von Cronjobs ist nicht bei jedem Host Provider gleich. Kontaktieren Sie bei Unklarheiten Ihren Provider.

Hier ein Beispiel eines cronjobs:



Der Befehl im Detail:
/usr/bin/php5 /home/www/webxx1/html/wetterseite/import/import-live.php >& /dev/null
(Dateiname und Verzeichnis anpassen)


keine Cronjobs möglich ?


Es gibt diverse Software und auch Webdienste, welche das Aufrufen der Datei in Intervallen übernehmen können. Ich möchte dazu aber keine Empfehlung abgeben.






Tutorial - Wetterdaten und Datenbanken - Teil 4 - Datenbank Abfragen

Teil 4 - Datenbank Abfragen


Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch


In diesem Teil werde ich einige Datenbank Abfragen aufzeigen.


Grundlagen:


In Teil 3 haben wir den sql-Befehl "INSERT INTO" verwendet, um Daten in die Tabelle einzufügen. Um Daten aus der Datenbank "herauszuholen", verwenden wir nun den Befehl "SELECT".

Hier ein Beispiel eines einfachen SELECT-Befehl:

SELECT temp FROM wettertabelle

(Diese Abfrage würde sämtliche Zeilen der Spalte "temp" aus der Tabelle "wettertabelle" ausgeben.)


Ein erster Versuch mit phpMyAdmin:


Wir verwenden für unseren ersten Versuch die SQL Eingabe von phpMyAdmin, und geben die Beispiel Abfrage ein:


1. Testen Sie folgende Abfrage:

SELECT temp FROM wettertabelle


sql-Befehl in phpMyAdmin

Sie sehen nach der Ausführung, dass MySQL die Spalte "temp" ausgegeben hat:





2. Oft werden mehrere Spalten einer Tabelle benötigt. Versuchen Sie mit diesem SQL-Befehl zusätzlich die Spalte "datetime" auszugeben.


SELECT datetime, temp FROM wettertabelle


3. Sie können auch einfach alle Spalten ausgeben lassen:

SELECT * FROM wettertabelle


Tutorial - Wetterdaten und Datenbanken - Teil 4.1 - Abfragen mit SQL

Teil 4.1 - Abfragen mit SQL


Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch


Hier einige oft benutzte Abfragen kurz erklärt.

1. Spalten umbennenen


Manchmal kann es auch Hilfreich sein, Spalten mit "AS" umzubenennen:

SELECT datetime AS Datum, temp AS Temperatur FROM wettertabelle



2. Das Datum zerlegen


Ein wichtiger Teil dürfte die Eingrenzung der Ausgabe nach Datumskriterien sein. Versuchen wir Datum und Zeit zu trennen und in separaten Spalten auszugeben:

SELECT DATE(datetime), TIME(datetime), temp FROM wettertabelle

Die Ausgabe:





Ein weiteres Beispiel:

SELECT YEAR(datetime), HOUR(datetime), temp FROM wettertabelle



3. Ausgabe mit WHERE eingrenzen


Mit WHERE lässt sich die Ausgabe nach beliebigen Kriterien Filtern:

SELECT DATE(datetime), TIME(datetime), temp FROM wettertabelle

WHERE temp < 0


... hier zusammen mit einer Datumsfunktion
SELECT DATE(datetime), TIME(datetime), temp FROM wettertabelle

WHERE YEAR(datetime) = '2013'

... oder beides zusammen:
SELECT DATE(datetime), TIME(datetime), temp FROM wettertabelle

WHERE YEAR(datetime) = '2013' AND temp < 0



4. Sortierung


Versuchen wir mit ORDER BY, die niedrigste Temperatur zu finden:

SELECT temp FROM wettertabelle

ORDER BY temp ASC


und jetzt die höchste:

SELECT temp FROM wettertabelle

ORDER BY temp DESC



5. Die Anzahl Zeilen limitieren

Mit LIMIT lässt sich die Ausgabe auf eine bestimmte Anzahl begrenzen.
Möchte man die Ausgabe auf z.B 10 Zeilen begrenzen:

SELECT temp FROM wettertabelle

LIMIT 10
(hier werden die Zeilen 1-10 ausgegeben)


Man kann bei LIMIT, auch die "Anfangszeile" mitgeben:

SELECT temp FROM wettertabelle

LIMIT 11,10
(hier werden die Zeilen 11-20 ausgegeben)



6. (Gruppen)Funktionen


Die wichtigsten Funktionen sind avg, min, max, sum und count. Sie sind eigentlich nur mit Gruppen sinnvoll. (siehe nächster Abschnitt: Gruppen).

Versuchen wir die Durchschnittstemperatur zu ermitteln:

SELECT AVG(temp) FROM wettertabelle


Maximale Temperatur:

SELECT MAX(temp) FROM wettertabelle

Minimale Temperatur:

SELECT MIN(temp) FROM wettertabelle

Anzahl Zeilen:

SELECT COUNT(*) FROM wettertabelle



7. Gruppen


Mit GROUP BY lassen sich leicht Zusammenfassungen erstellen. 
Sollen Beispielsweise die Jahresdurchschnittstemperaturen ermittelt werden, müssen die Jahre gruppiert werden.

SELECT AVG(temp) FROM wettertabelle
GROUP BY YEAR(datetime)

Hier wäre noch die Ausgabe des jeweiligen Jahres sinnvoll:

SELECT YEAR(datetime), AVG(temp) FROM wettertabelle
GROUP BY YEAR(datetime)


Hier werden Monatsdurchschnitte für alle Jahre ausgeben:

SELECT AVG(temp) FROM wettertabelle
GROUP BY MONTH(datetime)


Hier werden Monatsdurchschnitte für jedes Jahr getrennt ausgeben:

SELECT AVG(temp) FROM wettertabelle
GROUP BY YEAR(datetime), MONTH(datetime)


Hier werden Min/Max/Avg für jeden Tag ausgegeben:

SELECT MIN(temp), MAX(temp), AVG(temp) FROM wettertabelle
GROUP BY DATE(datetime)



Achtung 1: Diese Spalte "temp" macht so keinen Sinn.

SELECT temp FROM wettertabelle
GROUP BY YEAR(datetime)



8. Reihenfolge


Wichtig: Werden die obigen "Klauseln" kombiniert, muss eine bestimmte Reihenfolge eingehalten werden.

Für die Aufgezeigten gilt:

SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
LIMIT



Weiter mit Teil 4.2 - Abfragen mit PHP




Tutorial - Wetterdaten und Datenbanken - Teil 4.2 - Abfragen mit PHP

Teil 4.2 - Abfragen mit PHP

Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch


Um die Werte der Tabelle auf einer Webseite anzuzeigen, können wir html und php verwenden.


1. Zuerst mit der Datenbank verbinden (mysqli):


<?php

//db verbindung
$link = mysqli_connect("Hostname", "Username", "Password", "DBname");
(Mit Ihren Zugangsdaten ersetzen)



2. Die sql-Query:


Dann die sql-Abfrage in $query:
$query = "

SELECT datetime, temp
FROM wettertabelle
ORDER BY temp DESC
LIMIT 10

";



3. Die Ausgabe


Wir machen das Resultat in $result verfügbar:

$result = mysqli_query($link,$query);



Mit dieser while-Schlaufe werden dann alle Zeilen mit echo ausgegeben:

while($row = mysqli_fetch_array($result))
{

echo $row['temp'];

}



4. Resourcen freigeben


Zum Schluss die Ressourcen freigeben:

mysqli_free_result($result);

?>



4. Zusammenfassung:


<?php

//db verbindung
$link = mysqli_connect("Hostname", "Username", "Password", "DBname");

//db sql abfrage

$query = "
SELECT datetime, temp
FROM wettertabelle
ORDER BY temp DESC
LIMIT 10
";

//resultat verfügbar machen
$result = mysqli_query($link,$query);

//Zeilen ausgeben
while($row = mysqli_fetch_array($result))
  {
  echo $row['temp'];
  }


// ressourcen freigeben
mysqli_free_result($result);

?>


5. Ausgabe anpassen:


Die Ausgabe kann sehr vielfältig erfolgen. Um die Möglichkeiten aufzuzeigen, hier ein einige Beispiele:



5.1 Variablen Verbinden:


Um die Abfrageergebnisse übersichtlicher ausgeben zu können, erweitern wir das echo um Spaltennamen und einen Zeilenumbruch. Textelemente (z.B. "Datum/Zeit: ") und Variablen (z.B. $row['datetime']) werden mit einem Punkt (.) verbunden. Der Zeilenumbruch in html (<br>) sowie für den Quelltext (\n).

echo "Datum/Zeit: ".$row['datetime']." Temperatur: ".$row['temp']."<br>\n";



5.2 Beispiel mit Ausgabe mit einer html Tabelle:


//Tabelle öffnen
echo "<table border=\"1\"> \n";

//Überschriftenzeile ausgeben
echo "<td>Datum und Zeit</td><td>Temperatur</td>\n";


//Zeilen ausgeben
while($row = mysqli_fetch_array($result))
  {
  echo "<tr>\n";
  echo "<td>".$row['datetime']."</td>"."<td>".$row['temp']."</td>\n";
  echo "</tr>\n";
  }

//Tabelle schließen
echo "</table>\n";

Beachten Sie in Zeile 2 wie die Anführungszeichen mit \ maskiert werden müssen. Diese werden ansonsten nicht ausgegeben und brechen die Ausgabe vorzeitig ab.  "1" zu \"1\"




5.3 Einzelne Werte Darstellen:


Oft möchte man in einer bestehenden Webseite die aktuellen Werte darstellen. Zuerst passen wir die sql-Abfrage so an, dass jeweils nur der aktuellste ausgegeben wird :

$query = "

SELECT temp, hum, pressure
FROM wettertabelle
ORDER BY datetime DESC 
LIMIT 1

";


Wir möchten die Werte evtl. auch mehrmals auf der Seite einsetzen. Die Abfrage dabei jedesmal neu ausführen zu lassen, wäre nicht optimal. Wir werden also die Werte nicht sofort mit echo ausgeben, sonden in eine neue Variable überführen. Diese Variable können wir dann bequem überall auf der Seite ausgeben:

while($row = mysql_fetch_array($result))
{

$temperatur_aktuell = $row['temp'];
$luftfeuchte_aktuell = $row['hum'];
$luftdruck_aktuell = $row['pressure'];

}


Ausgegeben werden die Werte dann z.B. so:

Die aktuelle Temperatur: <?php echo $temperatur_aktuell; ?>


Unser php script erzeugt nun keine Ausgabe mehr. Es kann also in den Header der bestehenden Website eingefügt werden. Die Abfrage wird dann zu Beginn ausgeführt und die Daten stehen in den Variablen bereit.

Hier ein Besipiel mit html:

<html>
<head>


<?php

//db verbindung
$link = mysqli_connect("Hostname", "Username", "Password", "DBname");

//db sql abfrage
$query = "
SELECT temp, hum, pressure
FROM wettertabelle
ORDER BY temp DESC
LIMIT 10
";

//resultat verfügbar machen
$result = mysqli_query($link,$query);

//werte in variablen speichern
while($row = mysqli_fetch_array($result))
{

  $temperatur_aktuell = $row['temp'];
  $luftfeuchte_aktuell = $row['hum'];
  $luftdruck_aktuell = $row['pressure'];

}

// ressourcen freigeben
mysqli_free_result($result);

?>


<title>Unsere Wetterseite </title>

</head>

<body>

<h1>Willkommen auf unserer Wetterseite:</h1>

Die aktuelle Temperatur beträgt: <?php echo $temperatur_aktuell; ?> <br>

blabla...<br><br>
blablabla...<br><br><br><br>

Hier alle aktuellen Werte:<br>
<?php echo $temperatur_aktuell; ?><br>
<?php echo $luftfeuchte_aktuell; ?><br>
<?php echo $luftdruck_aktuell; ?><br>

</body>

</html>


Eine weitere Möglichkeit ist die Ausgabe der Daten mit einem Diagramm.
Siehe Tutorial: Diagramme mit amcharts


Tutorial - Wetterdaten Diagramme mit amcharts - Teil 3 - Datenquellen: MySQL Datenbank

Teil 3 - Datenquellen: MySQL Datenbank


Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch


Für die Speicherung von Wetterdaten eigenen sich Datenbanken besonders. Sie erlauben z.B. das schnelle filtern und sortieren umfangreicher Datenbeständen.

(Wie die Wetterdaten in eine Datenbank kommen wird später beschrieben.)

Die Datenbank

Hier die Struktur und einige Zeilen der Beispiel DB:









Die Datenabfrage

Nun  ein einfaches php script welches die gewünschten Daten aus der DB zieht.

Wir schreiben den php Code direkt in den  Datenbereich des Diagrammscripts.

var chartData = [   HIER DAS PHP SCRIPT   ];



1. Datenbankverbindung

Zuerst mit der Datenbank Verbindung aufnehmen:

mysql_connect("SQL Host", "Username","Password");
mysql_select_db("Database Name");
(mit Ihren Zugangsdaten ersetzen)

2. Die SQL Abfrage

Jetzt die MySQL Abfrage definieren:
$query = "

Zuerst wird das Feld Datetime zerlegt (dy, dm, dd etc) dann folgen die Wetterwerte "temp", "hum" und "pressure". Zudem wird die Monatszahl auf das Javascript Format geändert (-1).
SELECT YEAR(datetime) AS dy, MONTH(datetime) -1 AS dm, DAY(datetime) AS dd, HOUR(datetime) AS th, MINUTE(datetime) AS tm, temp, hum, pressure

Die Datenbanktabelle ausgewählt. (hier "wettertabelle")
FROM wettertabelle

Der Filter (hier mal nur Daten vom 25 Nov. 2013)
WHERE DATE(datetime) = '2013-11-25'

Sortiert nach Datum:
ORDER BY datetime


Hier nochmals die gesamte Abfrage der $query zugewiesen:
$query = "
SELECT YEAR(datetime) AS dy, MONTH(datetime) -1 AS dm, DAY(datetime) AS dd, HOUR(datetime) AS th, MINUTE(datetime) AS tm, temp, hum, pressure

FROM wtr2

WHERE DATE(datetime) = '$inputDate'

ORDER BY datetime
";


3. Die Ausgabe

Nun müssen wir die selektierten Daten mit echo ausgeben:

Wir beginnen mit:
$result = mysql_query($query)
OR die("Error: $query <br>".mysql_error());

while($row = mysql_fetch_array($result))
{

...dann das Echo:
echo "{date: new Date(".$row['dy'].",".$row['dm'].",".$row['dd'].",".$row['th'].",".$row['tm']."),t:".$row['temp'].",h:".$row['hum'].",p:".$row['pressure']."},";

Zur Erinnerung: Der echo Befehl sollte folgende Zeile ausgeben:
{date: new Date(2013,10,25,0,0),t:3.7,h:90.0,p:1022.9},

Klammer schließen:
};


Zusammenfassung:

Hier nochmals das gesamte php script:

<?php

//db verbindung

mysql_connect("Hostname", "Username","Password");
mysql_select_db("Database Name");



//db abfrage

$query = "
SELECT YEAR(datetime) AS dy, MONTH(datetime) -1 AS dm, DAY(datetime) AS dd, HOUR(datetime) AS th, MINUTE(datetime) AS tm, temp, hum, pressure

FROM wettertabelle

WHERE DATE(datetime) = '2013-11-25'

ORDER BY datetime
";


//ausgabe der zeilen

$result = mysql_query($query)
OR die("Error: $query <br>".mysql_error());

while($row = mysql_fetch_array($result))
{

echo "{date: new Date(".$row['dy'].",".$row['dm'].",".$row['dd'].",".$row['th'].",".$row['tm']."),t:".$row['temp'].",h:".$row['hum'].",p:".$row['pressure']."},";
   
};

?>


Bitte beachten:

Dieses Ausgabe enthält noch einen Fehler welcher bestimmte Browser (IE) evtl. abstürzen lassen kann. Schuld ist das letzte Komma im Datenbereich der echo Ausgabe. Es gibt diverse Methoden dieses Komma nicht auszugeben, würde jedoch die Überschaubarkeit dieses Beispiels sprengen. In Teil 3.1 wird eine mögliche Lösung aufgezeigt: Teil 3.1 - Datenbank Trennkomma

Tutorial - Wetterdaten Diagramme mit amcharts - Teil 3.1 - Datenbank Trennkomma

Teil 3.1 - Datenbank - Trennkomma


Achtung: Neue und aktualisierte Versionen der Tutorials finden Sie hier:

http://www.pscl.ch


Wie bereits erwähnt, sollte das letzte Trennkomma der Zeilen im Datenbereich des Diagramms, nicht ausgegeben werden.


1. Das Problem umkehren


Zur besseren Übersicht nehme ich das Komma mal in ein eigenes echo:

echo "{date: new Date(".$row['dy'].",".$row['dm'].",".$row['dd'].",".$row['th'].",".$row['tm']."),t:".$row['temp'].",h:".$row['hum'].",p:".$row['pressure']."}";

echo ",";

Nach der letzten Zeile soll dieses Komma nun nicht mehr ausgegeben werden.
Die erste Zeile ist aber einfacher zu erkennen als die letzte. Daher nehme ich zuerst das echo mit Trennkomma  nach vorne. 

echo ",";

echo "{date: new Date(".$row['dy'].",".$row['dm'].",".$row['dd'].",".$row['th'].",".$row['tm']."),t:".$row['temp'].",h:".$row['hum'].",p:".$row['pressure']."}";

Die neue Ausgabe wäre dann:

,{date: new Date(2013,10,25,0,0),t:1.1,h:82.0,p:1030.9,ws:2.7,wd:315.0,r:0.000,rs:0,wg:2.6,dp:-1.6,t2:3.1}
,{date: new Date(2013,10,25,0,5),t:1.1,h:81.0,p:1030.9,ws:2.3,wd:337.0,r:0.000,rs:0,wg:2.7,dp:-1.8,t2:3.1}

Nun muss also das erste Komma weg und nicht mehr das letzte. Das macht die Sache um vieles einfacher ;)


2. Variable


Nun müssen die Zeilen "unterscheidbar" gemacht werden. Ich verwende dazu eine Variable ($zeilenzaehler) welche sich nach dem ersten Durchlauf verändert.

Noch bevor die Ausgabe beginnt, eine Variable definieren.
$zeilenzaehler = 1;

Nach der ersten Zeilenausgabe mit echo wird dann die Variable geändert.
$zeilenzaehler = 2;

Bei der ersten Zeile ist die Variable noch "1", bei der zweiten dann "2".


3. Echo mit "If"


Mit einer "If" Funktion gebe ich nun das Komma nur dann aus, wenn die Variable $zeilenzaehler nicht "1" ist.
(Zur Erinnerung: Das Komma ist ja jetzt vor jeder Datenzeile. Dieses soll also nur ausgegeben werden, wenn es nicht die erste Zeile ist)

Zuerst mit "If" die Variable überprüfen. Solange $seitenzähler 1 ist, wird das folgende echo (mit dem komma) nicht ausgeführt:
if ($zeilenzaehler != 1)
{
   echo ",";
}
Im ersten Durchlauf ist $seitenzähler noch 1. Das echo mit dem Komma wird also nicht ausgeführt.


Dann das echo mit der Datenzeile: (wird in jedem Durchlauf ausgegeben)
echo "{date: new Date(".$row['dy'].",".$row['dm'].",".$row['dd'].",".$row['th'].",".$row['tm']."),t:".$row['temp'].",h:".$row['hum'].",p:".$row['pressure']."}";

Und jetzt, nachdem die erste Zeile (ohne Komma) bereits ausgegeben wurde, die Variable auf "2" ändern.
$zeilenzaehler = 2;

Bei allen weiteren Durchläufen ist die Variable nun 2. Die "Bedingung" der "If" Frage oben, ist also ab jetzt immer "wahr", und das Komma kommt nun vor jeder weiteren Datenzeile.


4. Zusammenfassung:


Hier noch das ganze php Script:

<?php

//db verbindung

mysql_connect("Hostname", "Username","Password");
mysql_select_db("Database Name");


//db abfrage

$query = "
SELECT YEAR(datetime) AS dy, MONTH(datetime) -1 AS dm, DAY(datetime) AS dd, HOUR(datetime) AS th, MINUTE(datetime) AS tm, temp, hum, pressure

FROM wettertabelle

WHERE DATE(datetime) = '2013-11-25'

ORDER BY datetime
";

// NEU: Variable definieren
$zeilenzaehler = 1;


//ausgabe der zeilen

$result = mysql_query($query)
OR die("Error: $query <br>".mysql_error());

while($row = mysql_fetch_array($result))
{


// echo

if ($zeilenzaehler != 1)
{
echo ",";
}

echo "{date: new Date(".$row['dy'].",".$row['dm'].",".$row['dd'].",".$row['th'].",".$row['tm']."),t:".$row['temp'].",h:".$row['hum'].",p:".$row['pressure']."}";

//Variable jetzt auf 2
$zeilenzaehler = 2;

};


Man kann das ganze selbstverständlich noch abkürzen, optimieren oder auch komplett anders machen ;)