Problem mit SQL-Statement
BlaBla
- programmiertechnik
0 Cheatah0 Der Martin
0 BlaBla0 ChrisB
0 BlaBla0 Der Martin
0 BlaBla
0 Sven Rautenberg0 BlaBla
Hallo und guten Abend!
Ich arbeite seit einigen Wochen an einen Web-Kalender. Hauptsächlich mit PHP und JavaScript. Als Backend MySQL-Server. Da ich gerade kräftig auf dem Schlauch stehe bzw. ein mittelgroßes Logikproblem habe darf ich hier um Denkanstöße oder Ideen bitten.
Also, nun zum Problem. Der Kalender hat verschieden Ansichen. Monats-, Wochen- und Listenansicht. Termine kann man u.A. mit Start- und End-Datetime erfassen. Die eingetragenen Termine werden jeweils nur für den angezeigten Zeitraum selektiert. Also bei Wochenansicht und KW1 z.B.:
SELECT * FROM tbl WHERE start >= '2011-01-03 00:00:00' AND end <= '2011-01-09 23:59:59'
Soweit so gut. Es gibt nun aber auch mehrtägige Termine. Wenn dieser nun z.B. am 01. Jänner beginnt und am 05. endet wird dieser mit oben angegeben Statement leider nicht selektiert. Angezeigt werden sollte er aber weil zumindest ein Teil des Termins in den Zeitraum fällt
Was tun?
Zunächst dache ich, dass ich den Zeitraum nach dem selektiert wird einfach erweitere. Ist aber nicht schön und verschiebt das Problem bestenfalls um x Tage.
Dann dachte ich, ich schreibe bei mehrtägigen Terminen einfach pro Tag einen Datensatz. Das Problem wäre damit gelöst. Schön finde ich das aber auch nicht. Vorallem weil in der Programmlogik dann einiges geändert werden müsste.
Am Liebsten wäre mir, wenn man das schon beim Selektieren der Datensätze lösen könnte. Hab aber gerade keine Idee wie so ein Statement aussehen könnet.
Vielleicht kann mir ja wer auf die Sprünge helfen oder hat andere Lösungsvorschläge.
Danke!
Karlo
Hi,
Vielleicht kann mir ja wer auf die Sprünge helfen oder hat andere Lösungsvorschläge.
Termine beginnen entweder im entsprechenden Zeitraum, oder sie enden in demselben.
Cheatah
Hallo,
Vielleicht kann mir ja wer auf die Sprünge helfen oder hat andere Lösungsvorschläge.
Termine beginnen entweder im entsprechenden Zeitraum, oder sie enden in demselben.
oder sie beginnen vor dem Zeitraum und enden erst danach.
Kurz gesagt: Das Ende der Veranstaltung muss nach dem Beginn des Zeitraums liegen, und der Beginn der Veranstaltung vor dem Ende des Zeitraums.
Ciao,
Martin
Hallo.
Termine beginnen entweder im entsprechenden Zeitraum, oder sie enden in demselben.
Hm... Oder sie beginnen vor dem entsprechenden Zeitraum, enden danach und durchlaufen den Zeitraum quasi. Das kann natürlich auch sein. Ich weiß momentan echt nicht wie ich das elegant lösen könnte.
lg
Karlo
Hi,
Termine beginnen entweder im entsprechenden Zeitraum, oder sie enden in demselben.
Hm... Oder sie beginnen vor dem entsprechenden Zeitraum, enden danach und durchlaufen den Zeitraum quasi. Das kann natürlich auch sein. Ich weiß momentan echt nicht wie ich das elegant lösen könnte.
In dem du genau diese drei Fälle in entsprechende Bedingungen umsetzt ...?
MfG ChrisB
Hi!
In dem du genau diese drei Fälle in entsprechende Bedingungen umsetzt ...?
Ja eh. Wenn ich wüsste wie.
Momentan fällt mir nur eine Lösung ein. Wenn ich einen mehrtägigen Termin erfasse, schreibe ich in eine weiter Tabelle die ID des Termins und alle Tage von Beginn bis Ende des Termins. Dann kann ich den Termin über ein Join ermitteln auch wenn Beginn und Ende vor bzw nach dem Zeitraum liegen. z.B so.
SELECT ...
FROM termine t, tage ta
WHERE
t.termin_id = ta.termin_id AND
ta.tag >= '2011-01-03 00:00:00' AND ta.tag <= '2011-01-09 23:59:59'
GROUP BY...
Das würde zwar funktionieren aber irgendwie hab ich das Gefühl, dass das auch einfacher gehen müsste.
lg
Karlo
Moin!
In dem du genau diese drei Fälle in entsprechende Bedingungen umsetzt ...?
Ja eh. Wenn ich wüsste wie.
Die Antwort steht im Thread.
- Sven Rautenberg
*Freu* Ich glaub ich habs doch noch geschafft das Ganze im Select-Statement zu lösen. Vielleicht interessiert es ja jemanden:
SELECT * FROM tbl
WHERE
(start >= '2011-01-03 00:00:00' AND end <= '2011-01-09 23:59:59') OR
( start >= DATE_ADD('2011-01-03 00:00:00', INTERVAL DATEDIFF(START ,END)DAY ) AND end <= '2011-01-09 23:59:59')
Ich ermittle also von mehrtägigen Terminen die länge in Tagen und ziehe diese vom eigentlichen Start-Zeitraum ab (genauer gesagt addiere ich einen negativen Wert). Ist zwar jetzt noch nicht 100% ausformuliert aber grundsätzlich sollte das funktionieren.
Danke und schönes Wochenende!
Karlo
Hallo,
SELECT * FROM tbl
WHERE
(start >= '2011-01-03 00:00:00' AND end <= '2011-01-09 23:59:59') OR
( start >= DATE_ADD('2011-01-03 00:00:00', INTERVAL DATEDIFF(START ,END)DAY ) AND end <= '2011-01-09 23:59:59')
>
> Ich ermittle also von mehrtägigen Terminen die länge in Tagen und ziehe diese vom eigentlichen Start-Zeitraum ab (genauer gesagt addiere ich einen negativen Wert).
sicher, es geht auch umständlich.
Der [direkte Ansatz](https://forum.selfhtml.org/?t=206203&m=1399207) wird übrigens noch anschaulicher, wenn man ihn negiert:
Eine Veranstaltung liegt \*nicht\* im Zeitfenster, wenn sie bereits vor dem Beginn des Zeitfensters endet oder erst nach dem Ende des Zeitfenster anfängt.
Ciao,
Martin
--
Männer haben nur eine Angst: Die Angst, kein Mann zu sein.
(Liv Tyler, US-Schauspielerin)
Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
Hi!
Der direkte Ansatz wird übrigens noch anschaulicher, wenn man ihn negiert:
Eine Veranstaltung liegt *nicht* im Zeitfenster, wenn sie bereits vor dem Beginn des Zeitfensters endet oder erst nach dem Ende des Zeitfenster anfängt.
Danke für die Unterstützung. Habs jetzt endlich kapiert :-)
Moin!
*Freu* Ich glaub ich habs doch noch geschafft das Ganze im Select-Statement zu lösen. Vielleicht interessiert es ja jemanden:
SELECT * FROM tbl
WHERE
(start >= '2011-01-03 00:00:00' AND end <= '2011-01-09 23:59:59') OR
( start >= DATE_ADD('2011-01-03 00:00:00', INTERVAL DATEDIFF(START ,END)DAY ) AND end <= '2011-01-09 23:59:59')
>
> Ich ermittle also von mehrtägigen Terminen die länge in Tagen und ziehe diese vom eigentlichen Start-Zeitraum ab (genauer gesagt addiere ich einen negativen Wert). Ist zwar jetzt noch nicht 100% ausformuliert aber grundsätzlich sollte das funktionieren.
Was ist mit Martins Lösung?
Dein Sichtfenster soll alle Termine anzeigen, die innerhalb des Zeitraums "wirken".
Das sind Termine, deren Start nach dem Beginn und deren Enddatum vor dem Ende des Fensters liegen.
Das sind Termine, deren Start vor dem Beginn und deren Enddatum vor dem Ende des Fenster liegen.
Das sind Termine, deren Start nach dem Beginn und deren Enddatum nach dem Ende des Fenster liegen.
Das sind Termine, deren Start vor dem Beginn und deren Enddatum nach dem Ende des Fensters liegen.
Das wären vier Bedingungen. Die kann man allerdings umformulieren, wie Martin es getan hat. Denn offenbar hat der Beginn für den Start eines Termins keine wirkliche Auswirkung, weil die Bedingung "vor" oder "nach" dem Beginn sein kann, in Abhängigkeit vom Enddatum, und umgekehrt.
Relevant für's Anzeigefenster sind ja alle Termine, die schon angefangen haben, bevor das Fenster endet, aber noch nicht geendet sind, bevor das Fenster überhaupt begonnen hat.
Das kann man auch beweisen, indem man die vier Bedingungen von oben umformuliert.
Zunächst mal gilt: Beginn < Ende
Und als Ungleichheitsketten formuliert gilt für die Daten bei den oberen vier Bedingungen:
Beginn < Startdatum < Enddatum < Ende
Startdatum < Beginn < Enddatum < Ende
Beginn < Startdatum < Ende < Enddatum
Startdatum < Beginn < Ende < Enddatum
Anhand dieser Schematik kann man erkennen, dass "Startdatum" sich immer vor "Ende" vom Fenster befindet, und "Enddatum" sich immer hinter dem "Beginn" befindet.
- Sven Rautenberg
Mahlzeit!
Das sind Termine, deren Start nach dem Beginn und deren Enddatum vor dem Ende des Fensters liegen.
Das sind Termine, deren Start vor dem Beginn und deren Enddatum vor dem Ende des Fenster liegen.
Das sind Termine, deren Start nach dem Beginn und deren Enddatum nach dem Ende des Fenster liegen.
Das sind Termine, deren Start vor dem Beginn und deren Enddatum nach dem Ende des Fensters liegen.
Ahhhja..., jetzt geht das Licht auf. Ich glaub gar nicht wie einfach das ist wenn man es mal begriffen hat.
Vielen Dank!