Frage zu einer SQL Auswertung -> Datumsbereich

Ich benötige da mal eure Hilfe …

Ich möchte aus meiner Datenbank die Zeilen auswerten, die im Bereich von Gestern bis 1 Woche zurück liegen und habe jetzt folgende Ansätze per Google gefunden, die aber für heute -7 Tage wären … :

$result = mysql_query("SELECT * FROM TABELLE where timestampintabelle < DATE_SUB(now(), INTERVAL 7 DAY)");

Das hier ist für Datum im Timestampformat !??

SELECT * FROM `testtable` where datum >= date_sub(NOW(), INTERVAL 7 DAY) order by datum asc

Welches Format muss hier vor liegen?

Wo liegt bei den Abfragen der Unterschied, also was genau machen diese Zeilen … und wie könnte ich meine Abfrage realisieren?

Das hier sollte zumindest das von gestern darstellen:

SELECT * FROM `testtable` WHERE TO_DAYS(DATUMSSPALTE) - TO_DAYS(NOW()) = -1

Wie muss da dann das Datumsformat sein … reicht ein String oder muss die SQL Spalte als DATE deklariert sein?

Würde dann auch das hier gehen:

SELECT * FROM `testtable` WHERE TO_DAYS(DATUMSSPALTE) - TO_DAYS(NOW()) BETWEEN '-1' AND '-7'

Gruß
Jens

Hi…

Du verwendest hier SQL-Funktionen. Dafür ist es unbedingt wichtig, dass du vorher klärst welche Engine du einsetzt und in welcher Version. Nur wenn deine Engine diese Funktionen beherrscht, dann kannst du sie auch verwenden.

Ich gehe mal stark davon aus, dass es standard SQL-Format ist. Also ein Feld vom Typ Date.

Mach es doch im Zweifelsfall nativ mit PHP - das geht immer.


$LetzteWoche = date("\"Y-m-d\"", time()-(7*24*60*60));  // Jetzt minus 7 Tage umgerechnet in Sekunden 
$Gestern = date("\"Y-m-d\"", time()-(24*60*60)); // Jetzt minus 24 Stunden

$sql = 'SELECT nadel FROM heuhaufen WHERE datum > '.$LetzteWoche.' AND datum < '.$Gestern ;

Für die Formatierung diesen link mal ansehen: Klick

Gruß,

Toni

Hallo Toni,
hallo Jens,

der Ansatz vom Jens ist genau richtig, solche Funktionalitaeten im SQL Aufruf zu machen. Wir reden hier mit Sicherheit vom mySQL, und da mache ich es in der Firma auch so, zum Teil inzwischen auch mit Store procedure. In der Doku zu mySQL ist es uebrigens ganz eindeutig beschrieben, wie der Befehl anzuwenden ist. Ich muesste da auch erstmal nachschauen, das kann aber eigentlich der Jens auch selbst, oder?

Sicherlich. Aber wo wir grad bei „Firma“ sind… Bei uns wird im Schichtenmodell gearbeitet. Dein Vorschlag geht eventuell für mySQL aber nicht unter Interbase oder unter PostgreSQL aber nicht MSSQL u.s.w. Zwar unter mySQL 5.0 aber nicht unter 4.x etc… Das muss man halt vorher recherchieren. Sowas gibts bei uns nicht. Nur ANSI SQL, und davon auch nur das gängigste. Wenn du mal versucht hast ein „gewachsenes Access-Projekt“ nach mySQL zu portieren, weisst du was ich meine. Der blanke Horror. mySQL 4 zum Beispiel, meine ich, unterstützte auch garkeine SPs…

Also mein Fazit: Beide Wege sind richtig. Einen falschen Weg gibt es IMO auch nicht. Man muss sich nur überlegen ob und was man sich für „Nebenwirkungen“ einkauft. Der unbedarfte User kann das nicht. Und darum: - Keep it as simple as possible -

Ist ja nun auch nicht die Hammeranwendung, die Prozesskapazität auslagern müsste… :wink:

Toni

Hallo ihr zwei, danke erst einmal für eure Antworten.

Ich benutze mysql-essential-5.0.51b auf einem WHS und habe auch schon in der Hilfe zum Progeamm nachgeschaut … aber irgendwie ist da nicht genau der Fall den ich benötige. Aus diesem Grund habe ich ja auch schon über Google gesucht und die von mir geposteten Beispiele gefunden.
Dadurch das ich allerdings noch nie wirklich mit mySql gearbeitet habe, war eine „Deutung“ der Abfragen auch etwas schwierig. Deswegen hatte ich auf eure Meinung bzw. Hilfe gehofft.
Klar geht im Notfall auch direkt PHP, aber wenn mysql schon die Funktion anbietet, warum dann nicht nutzen.?

Die beiden ersten Abfragen sind fast identisch, aber eben nur fast. Könnte mir evtl. jemand erklären was genau da jetzt abläuft … also wenn beide das gleiche Ergebnis liefern, warum dann so unterschiedliche Schreibweisen?

Das erste ist doch: Suche alle Termine, die kleiner sind als heute minus 7 Tage … aber was macht dann die 2. Lösung?
Das >= ist doch nur eine andere Schreibweise als BETWEEN … oder doch nur einfach größer oder gleich? das order by datum ist die ausgabe geordnet nach datum … aber wofür steht das „asc“ ?
Warum funktionieren beide Schreibweisen, hängt das damit zusammen das das eine Datum evtl.so geschrieben ist YYYY-MM-DD und das andere Timestamp ist? Wäre jetzt nur ein Erklärungsversuch …

Gruß
Jens

Hallo Jens,

bin leider nicht zu Hause, kann Dir also deshalb nur aus dem Gedaechtnis Erklaerungen versuchen zu liefern:

genau davon bin ich ausgegangen, sonst haettest Du naemlich nicht die mySQL Syntax benutzt. Das kann man aber nur sehen, wenn man damit sehr viel macht…

Die beiden ersten Abfragen sind fast identisch, aber eben nur fast. Könnte mir evtl. jemand erklären was genau da jetzt abläuft … also wenn beide das gleiche Ergebnis liefern, warum dann so unterschiedliche Schreibweisen?

Das erste ist doch: Suche alle Termine, die kleiner sind als heute minus 7 Tage … aber was macht dann die 2. Lösung?

dazu muesste ich auch in der Doku nachsehen…

Das >= ist doch nur eine andere Schreibweise als BETWEEN … oder doch nur einfach größer oder gleich? das order by datum ist die ausgabe geordnet nach datum … aber wofür steht das „asc“ ?

ASC ist die Richtung der anzuwendenen Sortierung des Ergebnisses, also ich glaube, das war absteigend.

Warum funktionieren beide Schreibweisen, hängt das damit zusammen das das eine Datum evtl.so geschrieben ist YYYY-MM-DD und das andere Timestamp ist? Wäre jetzt nur ein Erklärungsversuch …

ich glaube, der Timestamp wird in mySQL etwas anders verwendet wie der in PHP - aber vom Prinzip her muesste das so sein.

Das Standard-Datumsformat ist das ISO-Format, also YYYY-MM-DD (z.B. ‚2008-07-31‘), für Timestamps(ohne Zeitzone) entsprechend mit Uhrzeit

Um alle Werte des Vortages (Datum-Part) zu ermitteln, verwende ich z.B. eine Abfrage wie diese,wobei date eine Spalte vom Typ Date ist.

select * from tabelle where date = '2008-07-29' 

(nur dieser Tag wird angezeigt)

select * from tabelle where date between '2008-07-29' and '2008-07-30';

(Beide Tage werden angezeigt)

Für Spalten mit Timestamp

select * from tabelle where date(timestamp) = '2008-07-29'

(alles zwischen 0:00 und 23:59:59, date() ist eine Funktion, die den Datumsteil des Timestamps extrahiert)
oder

select * from tabelle where timestamp between '2008-07-29 00:00:00' and '2008-07-29 23:59:59'

Bei between sollte der kleinere Werte immer zuerst kommen.

Wenn man Datum und Zeit getrennt hat, kann man auch so etwas machen:

select * from tabelle where timestamp(date,time) between '2008-07-29 23:59:59' and '2008-07-30 12:00:00';

Allerdings wird der Zugriff langsam, wenn man auf der rechten Seite eine Funktion (hier timestamp() zur Typconvertierung) verwendet.

Die ganzen Funktionen sind aber auch ganz gut im Handbuch beschrieben.

Tommi

Hallo Tommi,

die Möglichkeit(en) hatte ich auch schon entdeckt, aber ich frage nicht nach einem festen Datum ab, sondern nur relativ zu heute bzw. gestern. D.h. ich muss erst einmal feststellen welcher Tag heute ist, bzw. gestern war und dann den Zeitraum davor (7 Tage) ermitteln und dann alles ausgeben was in dem Bereich liegt. Deswegen habe ich auch keine direkten Datumswerte verwendet.
Die letzte Abfrage … wenn man da den diekten Timestamp Wert nimmt, also ohne das in die Ausgabe YYYY-MM-DD HH:MM:SS zu verwandeln, gehts es dann genau so , nur schneller?

Gruß
Jens

Hallo Jens,
ich verwende folgendes zur Anzeige von Terminen, hier allerdings als „html“-Seite, die ich im Designer mit einem Browser-Objekt anzeige:

index.php

<html>
<head>
<link rel="stylesheet" type="text/css" href="./mystyle.css">
</head>
<body>
<?
require_once("./mysql.php");
$link=dbopen();
?>
<p>
<strong>heute</strong><br />
<?
$select = "SELECT Datum, Ereignis FROM termine.termine WHERE ( Datum = DATE_ADD(now(), INTERVAL 0 DAY))";
$query = mysql_query($select);
while($row = mysql_fetch_array($query)) {?>
<?echo $row['Ereignis'];?><br />
<?
}
?>
</p>
<p>
<strong>morgen</strong><br />
<?
$select = "SELECT Datum, Ereignis FROM termine.termine WHERE ( Datum = DATE_ADD(now(), INTERVAL 1 DAY))";
$query = mysql_query($select);
while($row = mysql_fetch_array($query)) {?>
<?echo $row['Ereignis'];?><br />
<?
}
?>
</p>
<p>
<strong>übermorgen</strong><br />
<?
$select = "SELECT Datum, Ereignis FROM termine.termine WHERE ( Datum = DATE_ADD(now(), INTERVAL 2 DAY))";
$query = mysql_query($select);
while($row = mysql_fetch_array($query)) {?>
<?echo $row['Ereignis'];?><br />
<?
}
mysql_close($link);
?>
</p>
</body>
</html>

mysql.php


<?
$MySQLHost="192.168.1.254";
$username="xxx";
$password="yyy";

function dbopen(){
   global $MySQLHost,$username,$password;
   $link = mysql_connect($MySQLHost, $username, $password) or die("Keine Verbindung möglich!");
   mysql_select_db("termine") or die("Auswahl der Datenbank fehlgeschlagen");
   return $link;
  }

?>

soweit richtig…

… aber ASC steht für ascending, was aufsteigend bedeutet
(die „Gegenrichtung“ wäre DESC (descending, absteigend))

Gruß, Peter

Danke erst einmal für eure Beiträge!
Werde mich dann am WE hoffentlich damit befassen können und die Varianten mal ausprobieren …

Gruß
Jens

Das macht keinen Unterschied:


 select * from tabelle where timestamp between (date_sub(now(),interval 7 day)) and now() order by timestamp desc;

oder

select * from tabelle where timestamp between (now()-interval 7 day) and now() order by timestamp desc;

bringt beides die letzten 7*24Std ausgehend von der aktuellen zeit, hier absteigend sortiert. Wenn man exakt von 0Uhr auslesen will, muss man nur den Time-Teil abschneiden.

Allerdings ist nur mysql so tolerant in der Syntax, für andere DBs muss man brav mit Funktionen und/oder CASTS arbeiten
Tommi

Falls es jemanden interessiert, das hier geht wunderbar, wobei man das entweder mit Unix Timestamp oder einer Datumsformatierten Spalte machen kann.

SELECT * FROM `testtable` where datum >= date_sub(NOW(), INTERVAL 7 DAY) order by datum asc

Das hier geht auch, allerdings muss die größere Zahl zuerst eingegeben werden, sonst gehts nicht!

SELECT * FROM `testtable` WHERE TO_DAYS(DATUMSSPALTE) - TO_DAYS(NOW()) BETWEEN '-7' AND '-1'

Gruß
Jens