BlaBla: Problem mit SQL-Statement

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

  1. 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

    --
    X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. 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

      --
      Denken ist wohl die schwerste Arbeit, die es gibt. Deshalb beschäftigen sich auch nur wenige damit.
        (Henry Ford, amerikanischer Industriepionier)
      Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    2. 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

      1. 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

        --
        RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
        1. 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

          1. 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

  2. *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

    1. 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:(
      
      1. 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 :-)

    2. 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
      
      1. 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!