php.de

Zurück   php.de > Webentwicklung > Datenbanken

Datenbanken SQL und Co

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 14.12.2007, 21:55  
Erfahrener Benutzer
 
Registriert seit: 21.10.2007
Beiträge: 125
prinzli
Standard BETWEEN Datumabfrage

Hallo zusammen... und da bin ich wieder..

Ich möchte eine Abfrage machen zwischen zwei Daten:

PHP-Code:
// Anzahl Datensätze abfragen
$anzahl_eintraege "SELECT COUNT(id) 
                    FROM 
                        benutzer_optionen
                    WHERE
                        geaendert
                    BETWEEN
                    '12.10.2006' AND '12.12.2007' "
;
                 
$anzahl_ausgabe    mysql_query($anzahl_eintraege) or die("Fehler in Zeile " __LINE__ " in der Abfrage " $anzahl_eintraege ", Fehlermeldung: " mysql_error());

$total    =  mysql_result($anzahl_ausgabe,0); 
..nur funktioniert dies nicht.
Wenn ich die Abfrage zum Beispiel mit der Spalte "ID" mache, also zB zwischen 5 und 40.. funktioniert es einwandfrei...

Fehlermeldung bekomme ich keine... die Ausgabe von $total ist 0, obwohl Datensätze vorhanden sind.

Das Datum wird in der Mysql-Datenbank in Format 10.10.2007 abgespeichert.
Habe schon versucht mit 10-10-2007.. funzt jedoch auch nicht...

.woran kann das liegen..?
Und welches Format zum abspeichern in der DB ist optimal..?

Vielen Dank im voraus..

Gruss Prinzli
prinzli ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 14.12.2007, 22:37  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Hallo prinzli,

das übliche Problem: Wenn du etwas in seiner String-Repräsentation sortierst (abstrakt gesehen ist dein BETWEEN ein solcher Fall), liegt die Priorisierung ganz klar bei: Anzahl Zeichen (zumindest bei nicht-lexikalischer Sortierung, also x < aa), Vergleich 1. Zeichen (a < b), Vergleich 2. Zeichen (aa < ab), usw.

Bei Datums (Daten?) liegt die Gewichtung aber auf Jahr ist gewichtiger als Monat, Monat ist gewichtiger als Tag.

Du siehst, diese beiden Priorisierungen kommen in Konflikt, wenn du ein Datum als String sortierst, das eine nicht normalisierte Form (YYYY-MM-DD) hat (z.B. wie deine: DD.MM.YYYY), denn dann ist plötzlich der Tag gewichtiger als der Monat oder das Jahr, denn der Tag steht weiter vorne im String als der Monat oder das Jahr. Genau das ist bei deinem Problem der Fall.

Darum existiert in MySQL z.B. auch der Spalten-Typ DATE (alternativ DATETIME, TIMESTAMP, INT) um deine Datums sortierbar (und damit auch für BETWEEN zugänglich) zu halten.

Hier (DATE) wird das Datum intern vermutlich als Integer gespeichert, in seiner String-Repräsentation aber im Format YYYY-MM-DD ausgegeben, was ja genau das Ziel ist: YYYY ist gewichtiger als MM ist gewichtiger als DD.

Ich empfehle dir also deine Datums grundsätzlich in diesem Spaltentyp abzulegen.
Es gibt eine Alternative, und zwar eine von MySQL zur Vergügung gestellte Funktion, die dir dein beliebiges Datumsformat in ein anderes (z.B. normalisiertes) umwandelt. Den Namen hat nikosch77 mal gepostet, hab ihn allerdings wieder vergessen, weil ich Datums grundsätzlich im DATE-Format in der Datenbank abspeichere (auch von der Performance her zu empfehlen). Vielleicht findest du ihn übers MySQL-Handbuch oder die Forensuche ja trotzdem, aber überleg erstmal, ob du dir nicht lieber die Mühe machen willst, gleich alles richtig im DATE-Format abzuspeichern.
Zergling-new ist offline   Mit Zitat antworten
Alt 14.12.2007, 23:28  
da schreibt der ElePHPant
 
Benutzerbild von Flor1an
 
Registriert seit: 18.06.2008
Beiträge: 8.903
PHP-Kenntnisse:
Fortgeschritten
Flor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer Anblick
Standard

Übrigens kann auch PHP wesentlich leichter mit diesem Format umgehen!

Z.b. kannst du das Datum ganz einfach in einen Timestamp umwandeln indem du
$timestamp = strtotime('YYYY-MM-DD'); // mit einem Datum aus der DB z.B.
aufrufst. Nur vorsichtig bei einem Datum vor 1970-01-01 liegt denn dahinter reicht der Timestamp nicht.

Umwandeln in ein, für deutsche Sicht, korrekte Darstellung kannst du wie folgt:

PHP-Code:
<?php
function date2datum($date) {
    
$date explode('-'$date);
    return 
$date['2'].'.'.$date['1'].'.'.$date['0'];
}
?>
Flor1an ist offline   Mit Zitat antworten
Alt 15.12.2007, 08:35  
Erfahrener Benutzer
 
Registriert seit: 21.10.2007
Beiträge: 125
prinzli
Standard

Guten Morgen

Vielen Dank Euren schnellen Antworten..!

@Zergling
Danke Deiner ausführlichen Erklärung..
Habe das Ganze nun in das "DATE" -Format geändert.. und super wie nun auch die Abfrage mit BETWEEN funktioniert..

@RaZoR
..irgendwie will diese Umwandlung nicht richtig funktionieren...
muss ich das ausgelesene Datum aus der DB erst in Timestamp umwandeln bevor die 2function date2datum" funktioniert..?

Das gehört wohl dann eher in die Rubrik "php für Anfänger"..

In meinem Beispiel das ausgelesene Datum (YYYY-mm-dd):
PHP-Code:
$dateorg $bo_zeile['geaendert']; 
Kannst Du mir nochmals auf die Sprünge helfen, wie ich nun weiter vorgehe um das Datum in "dd.mm.YYYY" umwandeln kann..?

Vielen Dank und Gruss
Prinzli
prinzli ist offline   Mit Zitat antworten
Alt 15.12.2007, 12:31  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Logischerweise muss es kein Timestamp sein, schau dir doch mal explode() an, es zerteilt einen String an einem festgelegten Zeichen ("-"). Offenbar bekommst du dann drei Teile, die du mit "." wieder neu zusammensetzt.

PHP-Code:
<?php
echo date2datum("2007-12-15"); // 15.12.2007
?>
vorausgesetzt du hast RaZoRs Funktion eingebunden.
Zergling-new ist offline   Mit Zitat antworten
Alt 16.12.2007, 21:49  
Erfahrener Benutzer
 
Registriert seit: 21.10.2007
Beiträge: 125
prinzli
Standard

Guten Abend...

..und alles funktioniert.. super..! danke vielmals...!

..nun habe ich no ein weiteres problem zu lösen zu BETWEEN:

Wenn ich jetzt nun eine Abfrage in einem bestimmten Zeitraum mache, zählt es mir ebenfalls die Datensätze mit 0000-00-00 (da in meinem Beispiel der Eintrag noch nicht geändert wurde und in der Spalte der DB mit dem Format DATE dieser Eintrag wohl automatisch eingetragen wird..?! )

Nun habe ich gelesen, dass es das sogenannte "NOT IN" gibt.. doch wie binde ich das nun funktionstüchtig in die DB Abfrage?

Abfrage:
PHP-Code:
// Anzahl Datensätze abfragen
            
$anzahl_eintraege "SELECT COUNT(id) 
                                FROM 
                                    benutzer_optionen
                                WHERE
                                    "
.$zr_spalte."
                                BETWEEN
                                '"
.$zr_spalte_suche_beginn."' AND '".$zr_spalte_suche_ende."' ";
                             
                                    
            
$anzahl_ausgabe    mysql_query($anzahl_eintraege) or die("Fehler in Zeile " __LINE__ " in der Abfrage " $anzahl_eintraege ", Fehlermeldung: " mysql_error());
            
            
$total    =  mysql_result($anzahl_ausgabe,0); 
Ich begrüsse Eure Hilfe..

Gruss Prinzli
prinzli ist offline   Mit Zitat antworten
Alt 16.12.2007, 22:45  
da schreibt der ElePHPant
 
Benutzerbild von Flor1an
 
Registriert seit: 18.06.2008
Beiträge: 8.903
PHP-Kenntnisse:
Fortgeschritten
Flor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer Anblick
Standard

Also ich kann mir ja garnich vorstellen dass 0000-00-00 auch zwischen zwei Dates fällt z.b. 2007-12-01 und 2007-12-31 da kann doch der Standardwert nicht vorkommen ?? Ich teste es mal aus!

Ansonsten einfach bei deiner Abfrage noch hinter der ersten Bedingung für WHERE dieses hier anhängen.

AND ".$zr_spalte." != '0000-00-00'

Damit schließt du halt aus dass $zr_spalte dieses Datum 0 hat.


*edit*

Also ich hab es bei mir nochmal getestet und kann wirklich nicht nachvollziehen wieso bei dir 0000-00-00 mit in den BETWEEN Bereich kommt?!?
Flor1an ist offline   Mit Zitat antworten
Alt 16.12.2007, 22:59  
Erfahrener Benutzer
 
Registriert seit: 21.10.2007
Beiträge: 125
prinzli
Standard

Hallo RaZoR

..bei der obigen Abfrage zählt es die Datensätze mit...

Nun habe ich
PHP-Code:
AND ".$zr_spalte." != '0000-00-00' 
eingebaut.. und nun gibt es mir die relevanten Daten aus..

Vielen Dank..!

Gruss Prinzli
prinzli ist offline   Mit Zitat antworten
Alt 16.12.2007, 23:53  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Zitat:
Zitat von RaZoR
Also ich kann mir ja garnich vorstellen dass 0000-00-00 auch zwischen zwei Dates fällt ..
Tut er auch nicht. Der Fehler liegt woanders, aber bestimmt nicht an BETWEEN oder DATE.
Zergling-new ist offline   Mit Zitat antworten
Alt 17.12.2007, 08:27  
Moderator
 
Benutzerbild von cycap
 
Registriert seit: 13.02.2008
Beiträge: 6.816
PHP-Kenntnisse:
Fortgeschritten
cycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nettcycap ist einfach richtig nett
Standard

Zitat:
Zitat von RaZoR
Übrigens kann auch PHP wesentlich leichter mit diesem Format umgehen!

Z.b. kannst du das Datum ganz einfach in einen Timestamp umwandeln indem du
$timestamp = strtotime('YYYY-MM-DD'); // mit einem Datum aus der DB z.B.
aufrufst. Nur vorsichtig bei einem Datum vor 1970-01-01 liegt denn dahinter reicht der Timestamp nicht.

Umwandeln in ein, für deutsche Sicht, korrekte Darstellung kannst du wie folgt:

PHP-Code:
<?php
function date2datum($date) {
    
$date explode('-'$date);
    return 
$date['2'].'.'.$date['1'].'.'.$date['0'];
}
?>
Wäre es nicht sinnvoller das ganze so zu machen?:

PHP-Code:
<?
date
("d.m.Y",strtotime("2007-12-17"));
?>
Naja egal, ich hab meinen Senf dazu gegeben :P
cycap ist offline   Mit Zitat antworten
Antwort


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.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
DATE_ADD und BETWEEN Cheesy Datenbanken 6 02.01.2008 19:47
Between - Abfrage geht nicht - Bitte um kurze Hilfe bendigo Datenbanken 2 02.08.2006 11:06
Between mit Datetime Feldern geht mir nicht bendigo Datenbanken 19 02.03.2006 19:59
between tommi89 Datenbanken 4 15.11.2005 10:21
Ich verstehe nicht, was daran falsch ist WHERE - BETWEEN tekknotrip Datenbanken 3 25.08.2005 15:45
Programmiersprache, nur welche? Off-Topic Diskussionen 27 28.07.2005 21:30
date between abfragen hekto Datenbanken 3 09.03.2005 21:17
Problem mit Between Abfrage Datenbanken 6 09.03.2005 15:27
BETWEEN und ORDER BY imported_dex Datenbanken 6 17.01.2005 16:18
between datum abfragen mysql hekto Datenbanken 2 12.01.2005 11:07
if und between sunset PHP Tipps 2005 12 11.01.2005 17:05
Fehler im BETWEEN Teil? R4v3r Datenbanken 4 22.11.2004 19:42
[Erledigt] between Datenbanken 1 18.10.2004 15:21

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php between, $date bestimmten tag des monats abfrage, datumabfrage html, php date2datum, date2datum.php, between datumsformat, php datumabfrage

Alle Zeitangaben in WEZ +2. Es ist jetzt 07:05 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum

Creative Commons License
Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.