SQL Abfrage - BETWEEN

fixxxxxi

Erfahrenes Mitglied
Hallo ich möchte eine SQL Abfrage machen, wo ich alle Daten zwischen dem heutigem Tage und einem Datum in der Vergangenheit habe. Dazu habe ich erstmal grob probiert. Das Format des Datums in der Tabelle ist d.m.Y .

Im Moment sieht meine Abfrage so aus, welche aber nicht funktioniert:

SQL:
SELECT `dates` FROM `tonacht_user_banlist_count` WHERE CONVERT( `tonacht_user_banlist_count`.`dates` USING utf8 ) BETWEEN  '20.06.2009'  AND '27.06.2009'

Wenn ich das BETWEEN weglasse also nur ein Datum auswähle funktioniert es, aber ich möchte ja alle Spalten zwischen den Daten auswählen :P

SQL:
SELECT `dates` FROM `tonacht_user_banlist_count` WHERE CONVERT( `tonacht_user_banlist_count`.`dates` USING utf8 ) '20.06.2009'

Wie muss die Abfrage richtig aussehen? LG Chris
 
Zuletzt bearbeitet von einem Moderator:
So... nun hab ich es anders versucht - Aber ich bekomme immer noch ein falsches Ergebnis angezeigt. Als Ergebnis wird an statt 14 die Zahl 48 ausgegeben! Was ist falsch?

PHP:
<?php
error_reporting(E_ALL);

include("../_mysql.php");
include("../_settings.php");
include("_functions.php");

$now = date("d.m.Y"); 

$bandauer='7';//wird später dynamisch geändert

$date = date("d.m.Y");
$date_new = date("d.m.Y", $time-(86400*$bandauer));

//Einträge in der SQL DB für die letzten 7 Tage:
//
//dates         count
//24.06.2009    2
//23.06.2009    4
//22.06.2009    1
//21.06.2009    3
//20.06.2009    3
//19.06.2009    1
//
// theoretisch sollte das Ergebniss $last7 = 14 sein bei 7 Tagen (alle counts addiert)

$last7 = mysql_num_rows(safe_query("SELECT count FROM ".PREFIX."user_banlist_count WHERE dates BETWEEN '$date_new' AND '$date'"));

echo $last7;
?>
 
Hallo!

Dein Problem düfte das Datumsformat sein.
Normalerweise wird das Datum im englischen Format (YYYY-MM-DD) in der Datenbank gespeichert.
Dann sollte ein SUM() auf die Spalte "count" in Verbindung mit BETWEEN eigentlich klappen.

Flexibler wärst Du allerdings wenn Du den Timestamp in der Datenbank eintragen würdest.

Gruss Dr Dau
 
Flexibler wärst Du allerdings wenn Du den Timestamp in der Datenbank eintragen

Das Format kann ich ja in einen Timestamp umwandeln. Aber in wie fern wär ich dann flexibler?

Ich habe nun beide Sachen probiert. Das sieht dann so aus:

PHP:
<?php
error_reporting(E_ALL);

include("../_mysql.php");
include("../_settings.php");
include("_functions.php");


$bandauer='7';//wird sp„ter dynamisch ge„ndert

$time= time();
$date = date("d.m.Y", $time);

$timestamp = strtotime ($date); 
$neue_timestamp = $timestamp - 86400*$bandauer; 
$date_new = date("d.m.Y", $neue_timestamp); 

//Eintr„ge in der SQL DB fr die letzten 7 Tage:
//
//dates         count
//24.06.2009    2
//23.06.2009    4
//22.06.2009    1
//21.06.2009    3
//20.06.2009    3
//19.06.2009    1
//
// theoretisch sollte das Ergebniss $last7 = 14 sein bei 7 Tagen (alle counts addiert)

$last7 = mysql_num_rows(safe_query("SELECT count FROM ".PREFIX."user_banlist_count WHERE dates BETWEEN '$date_new' AND '$date'"));

$last7sql = mysql_fetch_array(safe_query("SELECT SUM( count ) AS alle FROM ".PREFIX."user_banlist_count WHERE dates BETWEEN '$date_new' AND '$date'"));
$last7_neu = $last7sql['alle'];

echo $last7;// als ergebnis wird die Zahl 48 statt 14 ausgegeben
echo '<br>';
echo $last7_neu; // als ergebnis wird die Zahl 86 statt 14 ausgegeben
echo '<br>';
echo $date_new; //das datum wird korrekt ausgegeben! funktioniert - datum minus 7 tage!
?>

Hinter den // steht das was nun passiert :P LG
 
Hi,

folgendes müsste funktionieren (getestet):
PHP:
$bandauer = 7;

$sql = 'SELECT
			SUM(`count`) as `alle`
		FROM
			`' . PREFIX . 'user_banlist_count`
		WHERE
			`dates`
		BETWEEN
			"' . date('d.m.Y',strtotime('-' . $bandauer . ' days')) . '"
		AND
			"' . date('d.m.Y') . '"';

Allerdings stimme ich Dr Dau zu, du solltest ein Datum im passenden Format abspeichern.
 
Aber in wie fern wär ich dann flexibler?
Ich weiss ja nicht was Du mit der Spalte evtl. noch so alles anstellen willst, aber ein Timestamp lässt sich in jedes beliebige Datum und/oder Uhrzeit formatieren (z.B. mit DATE_FORMAT).
Ausserdem lässt sich mit einem Timestamp einfacher rechnen.

[edit]
Ähm, DATE_FORMAT konvertiert natürlich keinen Timestamp, sondern ein englisches Datums-/Uhrzeitformat in ein anderes Datums-/Uhrzeitformat.
Korrekt wäre FROM_UNIXTIME (gleiche Seite, etws weiter unten).
[/edit]
 
Zuletzt bearbeitet:
Das Problem ist, das die Daten beereits in die Tabelle eingetragen sind und das sind ca. 500 Spalten. Diese alle von Hand umzuändern... Naja... Egal.

Also wenn ich den Code so ausführe bekomme ich als Ergebnis 77 an statt eigentlich 14.

PHP:
$bandauer = 7;

$sql = 'SELECT
            SUM(`count`) as `alle`
        FROM
            `' . PREFIX . 'user_banlist_count`
        WHERE
            `dates`
        BETWEEN
            "' . date('d.m.Y',strtotime('-' . $bandauer . ' days')) . '"
        AND
            "' . date('d.m.Y') . '"';  
            
$show = mysql_fetch_array(safe_query("$sql"));
echo $show[alle];

Irgendwas scheint da nicht zu funtionieren. Ich habe das in der SQL Datenbank mal ausgeführt. Also folgende Abfrage:

SQL:
SELECT * FROM `tonacht_user_banlist_count` WHERE `dates` BETWEEN "20.06.2009" AND "27.06.2009"

Als Ergebnis, bekomm ich aber nicht nur die Daten angezeigt der letzten 7 Tage, sondern es wird nur der Tag beachtet. Monat und Jahr scheint nicht berücksichtigt zu werden. Es wird also der 20,21,22,23,24,25,26,27.JUNI - 20,21,22,23,24,25,26,27.MAI, 20,21,22,23,24,25,26,27.06 MÄRZ usw. ausgewählt.
 
Zuletzt bearbeitet von einem Moderator:
Wie gesagt, das Problem ist das falsche Datumsformat.
Wenn die Spalte als z.B. VARCHAR angelegt ist, dann liest MySQL das Datum von links nach rechts.
So ist z.B. der 21.05. zwischen dem 20.06. und dem 27.06.
Wenn die Spalte z.B. als INT angelegt ist, dann ist der Punkt ein Komma.
Wie MySQL mit dem 2. Punkt nun genau umgeht, habe ich keine Lust herauszufinden da es eh nichts am Problem ändern würde. ;)
Gut möglich dass MySQL das Jahr komplett ignoriert und aus dem Tag und Monat eine Ganzzahl mit Dezimalzahl macht.
21,05 liegt somit zwischen 20,06 und 27,06 (im grunde also genauso wie schon oben bei VARCHAR).

Schreibe Dir ein kleines Script welches das "Datum" (und die ID) ausliest, am Punkt zerpflückt (explode() ) und anschliessend im englischen Format (s.o.) wieder zusammen setzt (implode() ).
Per UPDATE änderst Du dann das Datum in der Tabelle mit Bezug auf die ID in das englische Datum um.
Danach (bloss nicht vorher) änderst Du dann den Spaltentyp für das Datum auf DATE.
Dann klappt's auch mit BETWEEN.

Für den Fall der Fälle solltest Du Dir natürlich erstmal ein Backup anlegen.

[edit]
@Loomes, prinzipiell funktioniert Deine Variante.
Allerdings nur wenn der Monat und das Jahr immer gleich sind.
[/edit]
 
Zuletzt bearbeitet:
Hi,

stimmt da hast du recht.
Zum umwandeln kann man aber auch folgendes SQL verwenden, was um einiges einfacher ist wie ich finde:
SQL:
UPDATE
			`table`
		SET
			`date` = STR_TO_DATE(`date`,"%d.%m.%Y")

Danach dann noch den Feld-Typ auf "Date" ändern.
 
Zuletzt bearbeitet von einem Moderator:
Ich hab die Daten so wie Loomes es vorgeschlagen hat in der DB umgewnadelt. Hat super geklappt. Auch funktioniert nun endlich die korrekte Ausgabe mit dem BETWEEN Befehl.

Aber auf die Spalten greifen noch andere PHPs zu, welche vorher das Datumsformat "d.m.Y" benutzten. Diese PHPs habe ich in soweit abgeändert, also einfach das Format in "Y-m-d" geändert. Dies funktioniert bei allen Dingen außer bei einer Datei, bzw. einem Teil dieser Datei.

Diese PHP erstellt dynamisch eine PNG aus den Daten count und date - ein Diagramm. Wenn ich mir die Tage (last=days) anzeigen lasse, funktioniert es einwandfrei. Wenn ich mir die Monate (last=months) anzeigen lassen will, funktioniert es seit dem ich das Datumsformat geändert habe nicht mehr.

Die Stelle an der die SQL Abfrage für Monate ist sieht wie folgt aus:

PHP:
	elseif($_GET['last'] == "months")
	{
		if(isset($_GET['count'])) {
			$count = (int)$_GET['count'];
			if($count <= 1) $count = 2;
			$_SESSION['count_months'] = $count;
		}
		elseif(isset($_SESSION['count_months'])) {
			$count = $_SESSION['count_months'];
		}
		else {
			$count = 12;
		}
		for($i = $count; $i > 0; $i--)
		{
			$month = 0;
			$monthquery = safe_query("SELECT count FROM ".PREFIX."user_banlist_count WHERE dates LIKE '%".date("Y-m-", mktime(0, 0, 0, date("m") - $i, 1, date("Y")))."'");
			while($dm = mysql_fetch_array($monthquery)) {
				$month += $dm['count'];
			}
			$array[] = $month;
		}
	}

Ich habe in diesem Abschnitt nur ".m.Y" in "Y-m-" geändert. Ein weiteres Problem, was ich habe, welche jedoch nicht mit dieser Datei zu tun hat ist folgendes.

In einer Tabelle habe ich die Hits gespeichert mit einem timestamp ip usw. Nun soll nur der Timestamp abgerufen werden, und die Anzahl der Hits von heute angezeigt werden, wenn die Timestamp eben das heutige Datum aufweißt. Aber das Ergebnis ist immer 0.

PHP:
$datecounter = date(time());
$counter_alle = mysql_num_rows(safe_query("SELECT timestamp FROM ".PREFIX."user_banlist_counter WHERE timestamp='$datecounter'"));

Auf jedenfall schonmal ein dickes Dankeschön für das Lösen des ersten Problems, auch wenn dadurch ein zweites entstand^^ LG Chris
 
Zurück