Ankündigung

Einklappen
Keine Ankündigung bisher.

[MySQL]Zeitüberschneidungen finden

Einklappen

Neue Werbung 2019

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

  • [MySQL]Zeitüberschneidungen finden

    Hallo Leute,

    ich sitze gerade vor einem Problem, was dringend gelöst werden muss, aber habe heute iwie nicht wirklich den Kopf dafür, wie es scheint.

    Durch einen Fehler in einem Script, wurden Termine für Benutzer eingetragen, die sich überschneiden. Das ein Benutzer nicht zur selben Uhrzeit an 2 Orten sein kann, sollte ja klar sein.

    Ich versuche jetzt via MySQL und PHP die Termine zu finden, die sich überschneiden.

    Ich arbeite über 3 Tabellen ( User, Zuweisungen, Termine ) mittels MySQL Joins. In der Tabelle Zuweisungen wird eben der User einem Termin zugewiesen. In der Termine Tabelle sind die Termininformationen ( Id, Start, Ende ) und in der User Tabelle eben Userdaten.

    Hier ein kleines Beispiel: Tabelle Zuweisungen:

    ID(Primary), Termin, User

    1, 1, Bernd
    2, 3, Hannes
    3, 8, Anna

    Tabelle Termine

    ID(Primary), Start(Unix Timestamp), Ende, Terminname
    1, DatumStart, DatumEnde, Termin 1
    3, DatumStart, DatumEnde, Termin x
    8, DatumStart, DatumEnde, Termin y

    Tabelle User

    ID, Name
    1, Bernd
    2, Hannes
    3, Anna

    Wie sollte ich über MYSQL ansetzen, um die Doppelten Termine für den jeweiligen USER auszugeben?
    Danke für die Hilfe.

  • #2
    Na nach den doppelten Terminen fragen, dann hast du doch auch die ID vom jeweiligen User.

    Edit: Die Tabellenstruktur kann man noch besser lösen. Die Tabelle Zuweisungen macht keinen Sinn, da du da eine typische Many-To-One Relation hast, wenn ich das richtig verstehe.
    Also ein User mit mehreren Terminen. Dafür müsstest du nur in der Termin-Tabelle die ID des Users speichern.
    Die mysql_* Erweiterung ist veraltet!
    Besser: mysqli_* oder (noch besser) PDO

    Kommentar


    • #3
      Das ist schon okay so,denke ich , denn ein Termin kann auch 50 Usern zugeschrieben werden.

      Kommentar


      • #4
        Gut okay, stimmt

        Ich bin nicht sicher ob es einfacher geht aber ich würde folgendes machen:
        - Alle Daten (also Datum) aus der Tabelle ziehen
        - Für jedes Datum alle Einträge raussuchen
        - Prüfen ob ein User dem Termin mehrmals zugeschrieben ist

        Edit: Achja dazu sei zu erwähnen, dass man natürlich mit Zeitspannen arbeiten muss.
        Die mysql_* Erweiterung ist veraltet!
        Besser: mysqli_* oder (noch besser) PDO

        Kommentar


        • #5
          Moin,

          habe mal versucht dein Szenario nachzustellen, Tabellennamen usw. sind ein bisschen anders.
          Nur grob getestet:
          Code:
          SELECT
             P.Pers_ID,
             P.Nachname,
             P.Vorname   
          FROM
             Person P     
          WHERE
             P.Pers_ID IN (
                SELECT
                   person_intern.Pers_ID            
                FROM
                   Person person_intern,
                   zuordnung zuordnung_intern,
                   termine termin_intern            
                WHERE
                   person_intern.Pers_ID = P.Pers_ID            
                   AND    zuordnung_intern.personid = person_intern.Pers_ID            
                   AND    zuordnung_intern.terminid IN (
                      SELECT
                         DISTINCT zuordnung.terminid                   
                      FROM
                         termine main                   
                      JOIN
                         termine terminJoin                     
                            ON main.Anfang BETWEEN terminJoin.Anfang AND terminJoin.Ende                     
                            AND main.ID != terminJoin.ID                  
                      JOIN
                         zuordnung                     
                            ON main.ID = zuordnung.terminid                   
                      JOIN
                         zuordnung subZ                     
                            ON zuordnung.personid = subZ.personid                     
                            AND zuordnung.ID != subZ.ID                 
                      )             
                   );
          EDIT: gerade gesehen, du wolltest ja eigentlich die Termine haben, meine Abfrage bringt dir den User der die Überschneidungen hat, aber das was du willst steckt ja mit drin.. hab ich dir also nicht zu viel abgenommen
          [COLOR=#A9A9A9]Relax, you're doing fine.[/COLOR]
          [URL="http://php.net/"]RTFM[/URL] | [URL="http://php-de.github.io/"]php.de Wissenssammlung[/URL] | [URL="http://use-the-index-luke.com/de"]Datenbankindizes[/URL] | [URL="https://www.php.de/forum/webentwicklung/datenbanken/111631-bild-aus-datenbank-auslesen?p=1209079#post1209079"]Dateien in der DB?[/URL]

          Kommentar


          • #6
            Vielen Dank erst einmal, ich habe dein SQL Query mal auf meine Tabellen/Spaltennamen angepasst:

            Code:
            SELECT
               P.id,
               P.f_name,
               P.l_name   
            FROM
               quietschies P     
            WHERE
               P.id IN (
                  SELECT
                     q_intern.id           
                  FROM
                     quietschies q_intern,
                     zuweisungen z_intern,
                     workshift w_intern            
                  WHERE
                     q_intern.id = P.id            
                     AND    z_intern.quietschi_id = q_intern.id           
                     AND    z_intern.shift_id IN (
                        SELECT
                           DISTINCT z_intern.shift_id                   
                        FROM
                          workshift main                   
                        JOIN
                           workshift terminJoin                     
                              ON main.start BETWEEN terminJoin.start AND terminJoin.end                    
                              AND main.ID != terminJoin.ID                  
                        JOIN
                           zuweisungen                    
                              ON main.ID = zuweisungen.shift_id                 
                        JOIN
                           zuweisungen subZ                     
                              ON zuweisungen.quietschi_id = subZ.quietschi_id                     
                              AND zuweisungen.ID != subZ.ID                 
                        )             
                     );
            Allerdings erhalte ich als Ergebnis die ID/ Name / Nachname aller User, auch wenn diese keine sich überschneidenten Schichten ( termine ) haben.

            Kommentar


            • #7
              PHP-Code:
              SELECT
                  z1
              .id
              FROM
                  zeiten z1
              INNER JOIN
                  zeiten z2 ON
                      
              (z1.startZeit BETWEEN z2.startZeit AND z2.endZeit)  # z2s___z1s___z2e   z1e
                      
              OR
                      (
              z1.endZeit BETWEEN z2.startZeit AND z2.endZeit)    # z1s   z2s___z1e___z2e
                      
              OR
                      (
              z2.startZeit BETWEEN z1.startZeit AND z1.endZeit)  # z1s   z2s___z2e   z1e 
              Grundsätzlich muss man ja nur wissen, welche Zeiten sich überschneiden. Da reicht das. Die Abfrage kann ja dann erweitert werden, wie bis alles andere damit abgefragt werden kann...

              Kommentar


              • #8
                Zitat von nameless97 Beitrag anzeigen
                Gut okay, stimmt

                Ich bin nicht sicher ob es einfacher geht aber ich würde folgendes machen:
                - Alle Daten (also Datum) aus der Tabelle ziehen
                - Für jedes Datum alle Einträge raussuchen
                - Prüfen ob ein User dem Termin mehrmals zugeschrieben ist

                Edit: Achja dazu sei zu erwähnen, dass man natürlich mit Zeitspannen arbeiten muss.
                Einfacher ginge das alles, wenn man die DB anweist, keine Überschneidungen zuzulassen. So wie es Unique Constraints gibt, die verhindern, daß Werte mehrfach vorkommen, gibt es Exclusion Constraints, mit denen man z.B. verhindern kann, daß ein User auf 2 sich überschneidenden Terminen ist.

                Code:
                test=*# create table termine (user_id int, termin tsrange, exclude using gist(user_id with =, termin with &&));
                CREATE TABLE
                Time: 234,396 ms
                test=*# insert into termine values (1, '[2014-11-02 08:00:00,2014-11-10 10:00:00)');
                INSERT 0 1
                Time: 0,662 ms
                test=*# insert into termine values (2, '[2014-11-02 08:00:00,2014-11-10 10:00:00)');
                INSERT 0 1
                Time: 0,198 ms
                test=*# insert into termine values (2, '[2014-11-02 09:00:00,2014-11-10 11:00:00)');
                ERROR:  conflicting key value violates exclusion constraint "termine_user_id_termin_excl"
                DETAIL:  Key (user_id, termin)=(2, ["2014-11-02 09:00:00","2014-11-10 11:00:00")) conflicts with existing key (user_id, termin)=(2, ["2014-11-02 08:00:00","2014-11-10 10:00:00")).
                Time: 0,483 ms
                Das funktioniert unabhänging vom Client und auch vom Wetter und dazu noch (da indexbasierter Constraint) rasend schnell. Und zwar mit PostgreSQL ab 9.3.
                PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                Kommentar


                • #9
                  Zitat von akretschmer Beitrag anzeigen
                  [...]
                  Das funktioniert unabhänging vom Client und auch vom Wetter und dazu noch (da indexbasierter Constraint) rasend schnell. Und zwar mit PostgreSQL ab 9.3.
                  Ich habe nur darauf gewartet . Diesmal ist der Hinweis jedoch lohnenswert .
                  [URL="https://github.com/chrisandchris"]GitHub.com - ChrisAndChris[/URL] - [URL="https://github.com/chrisandchris/symfony-rowmapper"]RowMapper und QueryBuilder für MySQL-Datenbanken[/URL]

                  Kommentar


                  • #10
                    Zitat von ChristianK Beitrag anzeigen
                    Ich habe nur darauf gewartet
                    Sorry. Konnte nicht eher.

                    Diesmal ist der Hinweis jedoch lohnenswert.
                    Das sind sie immer.
                    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                    Kommentar

                    Lädt...
                    X