IF (Mysql)

zmedia

Angesehenes Mitglied
Hallo zusammen

Habe da ein Problem was mich zu verzweiflung treibt.

Ich stelle Kalenderdaten eines bestimmten Wochentag in einem bestimmten Zeitraum dar.
CODE $date_from = new DateTime("2010-08-22");
$date_to = new DateTime("2011-07-22");

for ($date = clone $date_from; $date <= $date_to; $date->modify('next monday'))
{
// hier werden mit der IF Bedingung gewisse Tage ausgeblendet.
if($date < new DateTime("2010-12-20") or $date > new DateTime("2011-01-05"))
{
$tag =$date->format('d');
$monat =$date->format('M');
$woche =$date->format('W');
$jahr =$date->format('Y');
echo $tag.'-'. $monat.'-'.$jahr.'--'.$woche.$i.'<br />';
}

}


soweit so gut. Das funktioniert bestens.

In der if Bedungung ist eine Zeitspanne angegeben, welche im Kalender ausgeblendet wird. Nun habe ich aber mehrere Zeitspannen welche wiederum in einer MySQL DB gespeicht sind.
Die Tabelle beinhaltet nur die Daten der Ausblendzeiten und somit hat diese nur 3 Felder
ID|datum_event_start|datum_event_end

1|20-12-2010|05-01-2011
2|22-10-2010|02-11-2010
3|19-04-2011|30-04-2011

CODE $abfrage_kalenderdaten = mysql_query ("SELECT * FROM $tab_kalenderdaten");
while ($row = mysql_fetch_array ($abfrage_kalenderdaten))
{
$event_von = $row["datum_event"];
$event_bis = $row["datum_event_end"];
}


Nun mein Problem, wie bringe ich die zwei zusammen. Wenn ich eine while Schleife mache wird mir jedes Datum bei jedem Eintrag geschieben - also bei 2 Eintrgen kommt alles doppelt bei 3 alles 3x usw.

Wenn ich die while Schleife ausserhalt der if Bedingung mache wird nur jeweils der letzte durchgelaufene Datensatz genommen.

Wie stelle ich das an - hat mir jemand einen Tipp?

Danke
 
wie lautet denn die ausformulierte query? und wie ist die struktur der anderen tabelle?

damit:
CODE SELECT * FROM $tab_kalenderdaten

kann ja keiner was anfangen.

ich schätze aber, ein LEFT JOIN und BETWEEN könnten dich weiterbringen.
 
Es gibt nur eine Tabelle.

Alles was vorhanden ist, wurde oben gepostet!
 
mir erschließt sich - ehrlich gesagt - nicht der sinn dieses konstruktes ... das hier scheint mir einigermaßen logisch:

CODE
$date_from = new DateTime("2010-08-22");
$date_to = new DateTime("2011-07-22");

$abfrage_kalenderdaten = mysql_query ("SELECT * FROM $tab_kalenderdaten");

while ($row = mysql_fetch_array ($abfrage_kalenderdaten))
{
for ($date = clone $date_from; $date <= $date_to; $date->modify('next monday'))
{
// hier werden mit der IF Bedingung gewisse Tage ausgeblendet.
if($date < new DateTime($row["datum_event"]) or $date > new DateTime($row["datum_event_end"]))
{
$tag =$date->format('d');
$monat =$date->format('M');
$woche =$date->format('W');
$jahr =$date->format('Y');
echo $tag.'-'. $monat.'-'.$jahr.'--'.$woche.$i.'<br />';
}
}
}


wenn es das ist, solltest du dein konzept überdenken. schleifen in schleifen sind nicht unbedingt performant.

wenn nicht, solltest du dein problem anders ausformulieren. vielleicht bin ich aber auch nur zu dusselig, das zu verstehen.
 
Ich nutze innerhalb von Server-Daten unterschiedliche Kalendervarianten mit verschiedensten 'Markierungen'.

Das Prinzip ist aber immer dasselbe:

Eine Tabelle mit 'allen Datumsangaben' (ist schnell gemacht, da reicht das von 2000 - 2030).

Von dieser ein Left Join auf eine oder mehrere Unterabfragen, die jeweils 'besondere Tage' ausgeben, so daß man dann bsp. ein Flag 0 / 1 in eine zusätzliche Spalte schreibt.

Sehr grob:

CODE Select A.CalendarId,
A.thisDay,
CoalEsce(B2.flag, 0) As flag

From Calendar As A Left Join
(Select B1.von, B1.bis, 1 As flag
From Randdaten As B1) As B2
On A.thisDay Between B2.von And B2.bis

Where A.thisDay Between @Startdatum And @Enddatum


So kann man unterschiedlichste Kriterien per Unterabfrage ranhängen.

Ergebnis ist, daß man bei der Ausgabe lediglich ein Recordset einmal von oben nach unten durchlaufen muß und je nach gesetztem Flag den Hintergrund färbt oder andere Dinge anpaßt.

Das Zusammenfügen der Daten ist einfach in einer Datenbank sehr performant.
 
@Wurzel

Vom Prinzip her würde es stimmen, diese Version hatte ich auch schon versucht - das Problem hier ist dass nun pro Eintrag jeweils alle Dtum addiert werden. Sprich bei 2 Einträgen ich der DB kommen alle Daten Doppelt usw. DAS IST JA MEIN PROBLEM!


@Jürgen Auer

Ich will das ganze so dynamisch wie möglich gestalten, immer wieder alle Datum der kommenden Jahre manuell einzugeben finde ich schlecht.
 
Ich vermute mal eines von den beiden Dingern könnte passen, je nachdem, wie die Datenmenge und wie groß der Zeitraum ist. Ich bin mir aber auch nicht sicher, ob ich wirklich verstanden habe, was gemeint war. Aber ich dachte, ich gebe auch mal meine 2 Cent dazu.

1.)

CODE date_default_timezone_set('Europe/Berlin');

$date_from = new DateTime('2010-08-22');
$date_to   = new DateTime('2011-07-22');


/* Montage ermitteln */
$mondays = array();
for ( $date = clone $date_from; $date <= $date_to; $date->modify('next monday') )
{
   $mondays[] = clone $date;
}


/* Ausgabe der Montage */
for ( $i = 0; $i < count($mondays); $i++ )
{
   $date = $mondays[$i];
   $resource = mysql_query('SELECT * FROM ' . $tab_kalenderdaten . ' WHERE datum_event_start <= \'' . $date->format('Y-m-d') . '\' AND datum_event_end >= \'' . $date->format('Y-m-d') . '\'');
   if ( mysql_num_rows($resource) < 1 )  /* '> 0' fuer die Invertierung der Ausgabe  */
   {
       echo $date->format('d-M-Y--W') . '<br />' . "\n";
   }
   unset($date);
}




2.)


CODE date_default_timezone_set('Europe/Berlin');

$date_from = new DateTime('2010-08-22');
$date_to   = new DateTime('2011-07-22');

/* Datensaetze holen */
$kalenderdaten = array();
$abfrage_kalenderdaten = mysql_query('SELECT * FROM ' . $tab_kalenderdaten);
while ( $row = mysql_fetch_array ($abfrage_kalenderdaten) )
{
   $kalenderdaten[] = array(
       'start' => $row['datum_event_start'],
       'end' => $row['datum_event_end']
   );
}


/* Montage ermitteln */
$mondays = array();
for ( $date = clone $date_from; $date <= $date_to; $date->modify('next monday') )
{
   $mondays[] = clone $date;
}


/* Montage in Eventzeiten */
$monday_in_eventdate = array();
for ( $i = 0; $i < count($kalenderdaten); $i++ )
{
   $event_start = new DateTime($kalenderdaten[$i]['start']);
   $event_end = new DateTime($kalenderdaten[$i]['end']);
   for ( $j = 0; $j < count($mondays); $j++ )
   {
       if ( $mondays[$j] > $event_end ) { break; }
       if ( $mondays[$j] >= $event_start && $mondays[$j] <= $event_end && !in_array($mondays[$i]->format('Y-m-d'), $monday_in_eventdate) )
       {
           $monday_in_eventdate[] = $mondays[$j]->format('Y-m-d');
       }
   }
   unset($event_start);
   unset($event_start);
}


/* Ausgabe */
for ( $j = 0; $j < count($mondays); $j++ )
{
   if ( !in_array($mondays[$j]->format('Y-m-d'), $monday_in_eventdate) ) /* Invertierung durch weglassen des ! */
   {
       echo $mondays[$j]->format('Y-M-d--W') . '<br />' . "\n";
   }
}
 
Danke, für die Hilfe.

Leider ergeben beide deiner CODE fehler:

Code1:
Fatal error: Uncaught exception 'Exception' with message 'DateTime::__construct() expects parameter 1 to be string, object given' in /var/www/web21/html/test.inc.php:17 Stack trace: #0 /var/www/web21/html/test.inc.php(17): DateTime->__construct(Object(DateTime)) #1 /var/www/web21/html/index.php(160): include('/srv/www/web21/...') #2 {main} thrown in /srv/www/web21/html/test.inc.php on line 17


Code2:
Parse error: syntax error, unexpected '{' in /var/www/web21/html/test.inc.php on line 46


Ich schaue es mir spätern noch mal genauer an. Vielleicht findest Du aber den Fehler schon vorher.....

Fehler Code 2 gefunden:
CODE if ( !in_array($mondays[$j]->format('Y-m-d'), $monday_in_eventdate)) /* Invertierung durch weglassen des ! */


Da fehlte eine geschlossene Klammer.

Gibt mir dann aber nicht das richtige Ergebnis.

Ich erhalte ca. 52mal den 25.07.2011
 
Ich habe es mal leicht angepasst, aber es ist nicht ganz so leicht ohne es zu testen, alles komplett richtig zu schreiben.

Wieso es aber 52 Mal das Ergebnis ausgibt ist mir schleierhaft, vielleicht liegt es an falscher Verwendung der Klasse, denn das habe ich nur übernommen.


Funktioniert das erste Script den richtig? Die Ausgabe scheint richtig zu sein, die DB-Anbindung kann ich nur gerade nicht testen.
 
Bei mir klappt es nun:

QUOTE Start Script 2:
2010-Aug-22--33<br />
2010-Aug-23--34<br />
2010-Aug-30--35<br />
2010-Sep-06--36<br />
2010-Sep-13--37<br />
2010-Sep-20--38<br />
2010-Sep-27--39<br />
2010-Oct-04--40<br />
2010-Oct-11--41<br />
2010-Oct-18--42<br />
2010-Nov-08--45<br />

2010-Nov-15--46<br />
2010-Nov-22--47<br />
2010-Nov-29--48<br />
2010-Dec-06--49<br />
2010-Dec-13--50<br />
2011-Jan-10--02<br />

2011-Jan-17--03<br />
2011-Jan-24--04<br />
2011-Jan-31--05<br />
2011-Feb-07--06<br />
2011-Feb-14--07<br />
2011-Feb-21--08<br />
2011-Feb-28--09<br />
2011-Mar-07--10<br />
2011-Mar-14--11<br />
2011-Mar-21--12<br />
2011-Mar-28--13<br />
2011-Apr-04--14<br />
2011-Apr-11--15<br />
2011-Apr-18--16<br />
2011-May-02--18<br />

2011-May-09--19<br />
2011-May-16--20<br />
2011-May-23--21<br />
2011-May-30--22<br />
2011-Jun-06--23<br />
2011-Jun-13--24<br />
2011-Jun-20--25<br />
2011-Jun-27--26<br />
2011-Jul-04--27<br />
2011-Jul-11--28<br />
2011-Jul-18--29<br />



Nach dem Ausführen habe ich auch direkt den Fehler bekommen, das der entsprechende Hash-Index nicht vorhanden ist, ein Vorteil wenn man immer mit E_ALL | E_STRICT als Fehlerausgabe arbeitet...


PS: Die Datenbankdaten habe ich manuell hinzugefügt, da ich aktuell keinen Zugang zu einer DB habe.
 
Besten Dank Sascha

V1 geht genau in die richtige Richtung, das war mein Knoten - alle Tage in ein Array und dann mit einer for Schleife und der DB ausgrenzen - nicht umgekehrt wie ich das machten wollte.

Super, nun kann ich damit weiterarbeiten - Ich danke Dir und helfe Dir auch gerne einmal weiter.

Beste Grüsse

Nachtrag:

Wie ich nun bemerkt habe ist die Version2 Sinnvoller da bei V1 bei jedem Durchlauf der Tage die SQL Abfrage ausgeführt wird.
 
Zurück
Oben