Prüfen ob Termin in einem Zeitraum noch frei ist ... Hilfe!

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Prüfen ob Termin in einem Zeitraum noch frei ist ... Hilfe!

    Hallo zusammen,

    ich bin Anfänger und arbeite derzeit an einem Projekt.
    Dabei soll es sich um eine Art "Terminverwaltung handeln. (mit PHP, MySQL, usw.)

    Ein neuer Termin wird dabei über ein Formular erstellt. Nach Klick auf einen Submit-Button wird der Termin in die Datenbank geschrieben.

    Damit man sich etwas vorstellen kann - Hier ein Teil des Eingabeformulars:



    Hier ein Teil der Datenbank:



    Bitte die Datenbank ist derzeit noch fernab von Daten-Normalisierung, da ich viel rumprobiere...

    Zum Problem:

    Ich möchte jetzt bevor der neue Datensatz in die Datenbank geschrieben wird abfragen, ob der Termin noch frei ist.
    Es soll also geprüft werden, ob sich der Zeitraum des neuen Termines mit einem vorhandenem Termin in der Datenbank überschneidet.

    Kann mir dabei bitte jemand behilflich sein und mir einen einfachen Lösungsweg vorschlagen.

    Vielen Dank im Voraus!
    Zuletzt geändert von wahsaga; 21.01.2014, 09:49. Grund: Bitte unsinnge Verlinkungen bzw. Spam unterlassen!

  • #2
    Wo ist das Problem? Du sendest einen Query ab, der abfragt, ob das Datum innerhalb eines bestimmten Wertes liegst. Dazu benötigst du doch nur die PHP-Funktion date und BETWEEN von MySQL.

    Peter
    Nukular, das Wort ist N-u-k-u-l-a-r (Homer Simpson)
    Meine Seite

    Kommentar


    • #3
      Hallo,

      mag sein, dass ich zu kompliziert denke....

      Der neue Termin hat doch eine Start- und eine Endzeit. z.B.:
      Start: 21.01.2014 - 12:00 Uhr
      Ende: 21.01.2014 - 13:00 Uhr

      Ich müsste jetzt ja abfragen, ob irgendwann in dieser Stunde zw. 12:00 und 13:00 Uhr bereits ein Termin existiert und somit eine Überschneidung vorliegt.

      Vielleicht gibt es ja einen Termin, der um 12:45 anfängt und bis 13:00 dauert. Wie prüfe ich das ab?


      Wo ist das Problem? Du sendest einen Query ab, der abfragt, ob das Datum innerhalb eines bestimmten Wertes liegst. Dazu benötigst du doch nur die PHP-Funktion date und BETWEEN von MySQL.
      Ich könnte ja so nur die Startzeit mit der Datenbank vergleichen und nicht die gesamte Dauer meines Termines oder?
      Einen Termin der wie im obigen Beispiel um 12:45 anfängt erfasse ich so ja nicht.


      Vielleicht hast du ein kurzes Code-Snippet, damit ich mir etwas darunter vorstellen kannst, wie du genau vorgehen würdest.

      Vielen Dank

      Kommentar


      • #4
        Zitat von tomahawkv2 Beitrag anzeigen

        Ich möchte jetzt bevor der neue Datensatz in die Datenbank geschrieben wird abfragen, ob der Termin noch frei ist.
        Es soll also geprüft werden, ob sich der Zeitraum des neuen Termines mit einem vorhandenem Termin in der Datenbank überschneidet.
        Muß es zwingend MySQL sein?

        In PostgreSQL kannst das als exclusion constraint direkt in der Datenbank abbilden.
        Zuletzt geändert von wahsaga; 21.01.2014, 09:50.

        Kommentar


        • #5
          Hallo,

          Muß es zwingend MySQL sein?
          Sorry - Ja. Muss unter MySQL laufen.
          Muss das irgendwie lösen, komme aber ohne Hilfe nicht weiter.

          Danke

          Kommentar


          • #6
            Zitat von tomahawkv2 Beitrag anzeigen
            Hallo,

            Sorry - Ja. Muss unter MySQL laufen.
            Schlecht. Bekommt man mit viel Hirn sicher hin, aber in PG mit Range-Typen und Exclusion Constraint wäre es nicht nur absolut trivial, sondern auch noch sehr robust (weil als Table-Constraint) und schnell (weil Index-basiert)

            Es gibt da direkt Range-Typen (also es geht von-bis) und ein Overlapp-Operator, der Ranges auf Überlappung prüft, und Exclusion Constraint prüft, daß keine 2 sich überlappenden Ranges in der Tabelle stehen.

            Kommentar


            • #7
              Mach dir erst mal klar, welche Arten von Überlappungen es geben kann – „aufmalen” hilft!

              Daraus kann man dann recht einfach die notwendigen Bedingungen ableiten.
              I don't believe in rebirth. Actually, I never did in my whole lives.

              Kommentar


              • #8
                Ich glaube meine Kenntnisse übersteigt das um Längen.
                Werde das nicht ohne Hilfe auf die Reihe bekommen.

                Dachte nicht, dass das so komplex sei.

                Falls noch jemand eine Idee hat und mir helfen möchte ... - Untenstehend eine Visualisierung des Problems. Die Überlappung sollte mittels PHP, MySQL vermieden werden:




                Vielen Dank und schöne Grüße!

                Kommentar


                • #9
                  Zitat von tomahawkv2 Beitrag anzeigen
                  Ich glaube meine Kenntnisse übersteigt das um Längen.
                  Werde das nicht ohne Hilfe auf die Reihe bekommen.

                  Dachte nicht, dass das so komplex sei.
                  Vergleich einfach Anfangs- und Endzeiten, und vergleiche. Damit kannst das prüfen. Wenn die neue Anfangszeit nach einer schon eingetragenen ist und die dortige Endzeit danach überlappt es sich vorne. Das auch noch hinten prüfen.


                  So schwer ist es nun auch nicht. Was halt nicht geht: das direkt als Constraint abzubilden. Um mal zu zeigen, was ich meine:

                  Code:
                  test=*# create table buchung (dauer tsrange, exclude using gist (dauer with &&));
                  CREATE TABLE
                  test=*# insert into buchung values ('[2014-01-30 15:00:00,2014-01-30 15:45:00)');
                  INSERT 0 1
                  test=*# insert into buchung values ( '(2014-01-30 16:00:00,2014-01-30 17:00:00)');
                  INSERT 0 1
                  
                  -- nun ein Select, ob sich die Zeit überlappt:
                  
                  test=*# select * from buchung where  dauer && '(2014-01-30 16:30:00,2014-01-30 17:30:00)';
                                       dauer
                  -----------------------------------------------
                   ("2014-01-30 16:00:00","2014-01-30 17:00:00")
                  (1 row)
                  
                  
                  -- ein Insert, der aber scheitert aufgrund des Constraints
                  test=*# insert into buchung values ( '(2014-01-30 16:30:00,2014-01-30 17:30:00)');
                  ERROR:  conflicting key value violates exclusion constraint "buchung_dauer_excl"
                  DETAIL:  Key (dauer)=(("2014-01-30 16:30:00","2014-01-30 17:30:00")) conflicts with existing key (dauer)=(("2014-01-30 16:00:00","2014-01-30 17:00:00")).
                  STATEMENT:  insert into buchung values ( '(2014-01-30 16:30:00,2014-01-30 17:30:00)');
                  ERROR:  conflicting key value violates exclusion constraint "buchung_dauer_excl"
                  DETAIL:  Key (dauer)=(("2014-01-30 16:30:00","2014-01-30 17:30:00")) conflicts with existing key (dauer)=(("2014-01-30 16:00:00","2014-01-30 17:00:00")).

                  Kommentar


                  • #10
                    Zitat von pg_user Beitrag anzeigen
                    Vergleich einfach Anfangs- und Endzeiten, und vergleiche. Damit kannst das prüfen. Wenn die neue Anfangszeit nach einer schon eingetragenen ist und die dortige Endzeit danach überlappt es sich vorne. Das auch noch hinten prüfen.
                    Weil ich es grad sehe: speicher Zeitpunkte nicht mehrfach, das ist sehr redundant, was Du da mit je 3 Feldern machst. In MySQL heißt der passende Datentyp wohl DATETIME.

                    Kommentar


                    • #11
                      Hallo,

                      ich unternehme noch einen letzten Versuch:


                      Weil ich es grad sehe: speicher Zeitpunkte nicht mehrfach, das ist sehr redundant
                      Bitte lies kurz den Satz den ich genau unter dem Screenshot platziert habe.
                      Wenn die Sache gelöst ist, dann bin ich bereit alles umzuschreiben...

                      ----------------------------------------------------------------------------


                      Ich habe so begonnen:

                      Ich meine zu glaube, dass mir das folgende SQL-Statement alle möglichen Terminüberschneidungen liefert:

                      Code:
                       // $start_time_timestamp = Startzeit des neuen Termins
                       // $end_time_timestamp = Endzeit des neuen Termins
                        
                      SELECT * FROM `terminverwaltung_termine` 
                      WHERE start_time_timestamp BETWEEN '" . $start_time_timestamp . "' AND '" . $end_time_timestamp . "' 
                      OR end_time_timestamp BETWEEN '" . $start_time_timestamp . "' AND '" . $end_time_timestamp . "'
                      Hoffnungsvoll habe ich habe dann folgendes gecodet:

                      PHP-Code:
                      $ueberschneidung_query mysqli_query($verbindung"SELECT * FROM `terminverwaltung_termine` 
                      WHERE start_time_timestamp BETWEEN '" 
                      $start_time_timestamp "' AND '" $end_time_timestamp "' 
                      OR end_time_timestamp BETWEEN '" 
                      $start_time_timestamp "' AND '" $end_time_timestamp "'");

                       
                      $ueberschneidung_num_rows mysqli_num_rows($ueberschneidung_query);

                       if (
                      $ueberschneidung_num_rows 0) {

                        
                      // GIB EINEN FEHLER AUS!
                        
                       
                      } else {   
                        
                       
                      // SCHREIB DEN NEUEN DATENSATZ IN DIE DB!
                        
                       

                      Grundsätzlich funktioniert es, aber es gibt folgendes Problem:

                      Nehmen wir an es existiert bereits der folgende Termin:
                      Start: 10:00 Uhr
                      Ende: 11:00 Uhr

                      Der neue Termin sieht so aus:
                      Start: 09:00 Uhr
                      Ende: 10:00 Uhr

                      Der Termin wird nicht in die Datenbank geschrieben, da:
                      Ende "Neuer Termin" == Start "Bestehender Termin"


                      So jetzt müsste es dann so weitergehen:

                      PHP-Code:
                      $ueberschneidung_query mysqli_query($verbindung"SELECT * FROM `terminverwaltung_termine` 
                      WHERE start_time_timestamp BETWEEN '" 
                      $start_time_timestamp "' AND '" $end_time_timestamp "' 
                      OR end_time_timestamp BETWEEN '" 
                      $start_time_timestamp "' AND '" $end_time_timestamp "'");

                       
                      $ueberschneidung_num_rows mysqli_num_rows($ueberschneidung_query);

                        
                      // Wenn es eine Überschneidung gibt
                        
                      if ($ueberschneidung_num_rows 0) {
                       
                       
                      // Datensatz der möglichen Überschneidungen holen und Variablen setzen
                       
                      while ($row mysqli_fetch_array($ueberschneidung_query)) {
                         
                      $ueberschneidung_start $row["start_time_timestamp"]
                         
                      $ueberschneidung_ende $row["end_time_timestamp"]
                       } 
                        
                       if(
                      $start_time_timestamp == $ueberschneidung_ende || $end_time_timestamp == $ueberschneidung_start) {
                        
                       
                      // ALLES OK
                        // SCHREIB DEN NEUEN DATENSATZ IN DIE DB!
                        
                      } else {
                        
                        
                      // GIB EINEN FEHLER AUS!
                        
                      }
                      } ELSE {
                        
                        
                      // ALLES OK
                       // SCHREIB DEN NEUEN DATENSATZ IN DIE DB!
                        


                      Ich glaube zwar nicht, dass sich das jetzt jemand von euch durchschaut, aber einen Versuch ist es Wert. So hab' ich's wenigstens mal dokumentiert.

                      Ich kenn' mich nicht mehr aus. Als Anfänger ist mir das zu viel.
                      Kann dies so funktionieren?
                      Was ist wenn wenn das SQL-Statement mehr als einen Datensatz zurückliefert?

                      Hat jemand noch eine Idee?

                      Kommentar


                      • #12
                        Zitat von tomahawkv2 Beitrag anzeigen
                        Grundsätzlich funktioniert es, aber es gibt folgendes Problem:

                        Nehmen wir an es existiert bereits der folgende Termin:
                        Start: 10:00 Uhr
                        Ende: 11:00 Uhr

                        Der neue Termin sieht so aus:
                        Start: 09:00 Uhr
                        Ende: 10:00 Uhr

                        Der Termin wird nicht in die Datenbank geschrieben, da:
                        Ende "Neuer Termin" == Start "Bestehender Termin"
                        BETWEEN betrachtet IIRC die Grenzen inklusive. Um das zu verhindern kannst auch mit Größer/Kleiner - Zeichen arbeiten - ist natürlich auch wieder Aufwand. Oder ziehst am Ende 'ne Sekunde ab. (also vom Ende des neuen Termins)

                        Bei den Ranges-Typen in PG kann man das übrigens definieren: eckige Klammern inklusive, geschweite exclusive.

                        Kommentar


                        • #13
                          Zitat von tomahawkv2 Beitrag anzeigen
                          Ich meine zu glaube, dass mir das folgende SQL-Statement alle möglichen Terminüberschneidungen liefert:

                          Code:
                          […]
                          WHERE start_time_timestamp BETWEEN '" . $start_time_timestamp . "' AND '" . $end_time_timestamp . "' 
                          OR end_time_timestamp BETWEEN '" . $start_time_timestamp . "' AND '" . $end_time_timestamp . "'
                          Nein, da fehlt noch der Fall, dass ein bestehender Termin den neuen Termin vollständig enthält.

                          Nehmen wir an es existiert bereits der folgende Termin:
                          Start: 10:00 Uhr
                          Ende: 11:00 Uhr

                          Der neue Termin sieht so aus:
                          Start: 09:00 Uhr
                          Ende: 10:00 Uhr

                          Der Termin wird nicht in die Datenbank geschrieben, da:
                          Ende "Neuer Termin" == Start "Bestehender Termin"
                          BETWEEN prüft auf kleiner-gleich/größer-gleich.

                          Endzeitpunkt = 10:00 und Startzeitpunkt = 10:00 wird damit natürlich als „Überschneidung” gewertet. Den gleich-Fall musst du also jeweils ausschließen, wenn du diese Gleichheit nicht als „Überschneidung” betrachten willst.
                          I don't believe in rebirth. Actually, I never did in my whole lives.

                          Kommentar


                          • #14
                            Hallo,

                            also ich glaube fast, dass mir eure beiden Beiträge geholfen haben.

                            Um das zu verhindern kannst auch mit Größer/Kleiner - Zeichen arbeiten - ist natürlich auch wieder Aufwand. Oder ziehst am Ende 'ne Sekunde ab ...
                            Mein Code sieht jetzt so aus:

                            PHP-Code:
                             
                            // $start_time_timestamp = Startzeit des neuen Termins
                             // $end_time_timestamp = Endzeit des neuen Termins
                              
                             
                             // Auf Termin-Überschneidung prüfen
                            $ueberschneidung_query mysqli_query($verbindung"SELECT * FROM terminverwaltung_termine 
                            WHERE start_time_timestamp > '" 
                            $start_time_timestamp "' AND start_time_timestamp < '" $end_time_timestamp "'
                            OR end_time_timestamp > '" 
                            $start_time_timestamp "' AND start_time_timestamp < '" $end_time_timestamp "'");

                             
                             
                            // Nachschauen, ob das SQL-Statement ein Ergebnis geliefert hat
                             
                            $ueberschneidung_num_rows mysqli_num_rows($ueberschneidung_query);

                             
                              
                            // Wenn es mindestens eine Überschneidung gibt, dann ...
                              
                            if ($ueberschneidung_num_rows 0) {

                                
                            // GIB EINEN FEHLER AUS!
                             
                             
                            } else {   // Wenn es keine Überschneidung gibt, dann ...

                                // SCHREIB DEN NEUEN DATENSATZ IN DIE DB!

                             

                            Also ein erster Test sieht sehr erfolgsversprechend aus.
                            Ehrlich gesagt fühle ich mich noch immer sehr sehr unsicher und es fällt mir schwer zu glauben, dass jetzt alles passt mit so einfachen Code.

                            Kann das jetzt so funktionieren?

                            Vielen Dank nochmal für die Unterstützung!

                            Kommentar


                            • #15
                              Zitat von wahsaga Beitrag anzeigen
                              Nein, da fehlt noch der Fall, dass ein bestehender Termin den neuen Termin vollständig enthält.
                              I don't believe in rebirth. Actually, I never did in my whole lives.

                              Kommentar

                              Lädt...
                              X