Graphity: MySQL/ AND-OR SELECTs gleichzeitig

Hallo Forum

Ich habe folgendes Problem:
Ich habe mehrere Tabellen und muß diese Joinen. Das klappt ganz gut. Aber jetzt will mir nur bestimmte Daten anzeigen lassen und zwar auf jeden Fall die, wo urlaubdatum != current_date ist, aber auch die wo Raum entweder != 1.Dienst oder != 2.Dienst oder != FOÄ ist. Es ist praktisch folgender Select-Query:

select * from namen left join aerzte on namen.name = aerzte.arzt left join urlaub on urlaub.urlaubname = namen.name where urlaub != current_date and Raum != '1.Dienst' or Raum != '2.Dienst' or Raum != 'FOÄ';

Er zeigt mir jetzt aber alle Zeilen an, die nicht 1.Dienst usw. enthalten und nicht nur die die, wo urlaub != current_date ist.

Gibt's irgendwie ein Möglichkeit "Klammern" zu setzen? damit er weiß, daß die Raum-Argumente zusammengehören und nur eines von denen zutreffen muß, urlaubdatum aber auf jeden Fall?

thxINadvance
         Graphity

  1. Gibt's irgendwie ein Möglichkeit "Klammern" zu setzen? damit er weiß, daß die Raum-Argumente zusammengehören und nur eines von denen zutreffen muß, urlaubdatum aber auf jeden Fall?

    SELECT wasduwillst FROM tabelle WHERE bedingung1 AND bedingung2 AND bedingung2 HAVING bedingung4 OR bedingung5 OR bedingung6

    Ansonsten hilft auch http://www.little-idiot.de/mysql/ als Nachschlagewerk. :)

    - Sven Rautenberg

    1. Hi

      Gibt's irgendwie ein Möglichkeit "Klammern" zu setzen? damit er weiß, daß die Raum-Argumente zusammengehören und nur eines von denen zutreffen muß, urlaubdatum aber auf jeden Fall?

      Ja, die gibt es, benutze Klammern einfach

      select *    <- pfui (wieso steht sicher irgendwo im Archiv)
        from namen
         left join aerzte
              on namen.name = aerzte.arzt
         left join urlaub
              on urlaub.urlaubname = namen.name
        where urlaub != current_date
          and (Raum != '1.Dienst' or Raum != '2.Dienst' or Raum != 'FOÄ');

      SELECT wasduwillst FROM tabelle WHERE bedingung1 AND bedingung2 AND bedingung2 HAVING
      bedingung4 OR bedingung5 OR bedingung6

      Nein, having hat in diesem Zusammenhang nichts verloren. Was having macht, ist wenn du
      Groupingfunktionen hast wie sum und den zugehörigen Group By nach den where clauses
      noch Records rausfiltern, also auf dem Resultat. Das heisst, es wird ohne Indexzugriffe!
      nochmal ein Resulttablescan gemacht. Natürlich verlangsamt das stark und es sollte
      nur in Ausnahmefällen angewendet werden wenn eben beispielsweise nur Records mit
      sum > x ausgegeben werden sollen, also Daten die _vor_ dem group nicht verfügbar sind.

      Gruss Daniela

      1. Hallo

        <entschuldigung> Ich hatte am Freitag leider keine Zeit mehr, in das Forum zu schauen. Als ich einmal schauen wollte wurde es gerade "upgedated" </entschuldigung>

        <vorwarnung> Wenn ich jetzt (aus eigenem Fehler) keine Antwort bekomme, poste ich einen neuen Thread </vorwarnung>

        Ich habe die Syntax ausprobiert und (natürlich ;-) ) funktioniert sie. Ich habe aber wohl einen Dankefehler gemacht. Was ich eigentlich wollte ist folgendes:

        Das Ergebnis soll alle Namen enthalten, wo Urlaub != current_date ist und wo Raum != '1.Dienst' usw. Aber: Da man selten nur einen Tag Urlaub nimmt, sind mehrere Daten (Datums) in der Tabelle vorhanden (entsprechend lang ist natürlich die Liste). Mit der vorgegangenen Syntax werden auch die Namen ausgegeben, die am current_date urlaub haben, wenn sie irgendwann anders Urlaub genommen haben.
        Was ich also bräuchte währe theoretisch ein select auf urlaub, das den namen zurück gibt und das datum des current_date, wenn er vorhanden ist. Dieses select muß mit der tabelle namen gejoint werden und darauf ein select wo nur die namen angezeigt werden, an denen urlaubdatum nicht current_date ist.

        War das verständlich?

        danke
            Graphity

        1. Hi

          Das Ergebnis soll alle Namen enthalten, wo Urlaub != current_date ist
          und wo Raum != '1.Dienst' usw. Aber: Da man selten nur einen Tag Urlaub
          nimmt, sind mehrere Daten (Datums) in der Tabelle vorhanden (entsprechend
          lang ist natürlich die Liste). Mit der vorgegangenen Syntax werden auch
          die Namen ausgegeben, die am current_date urlaub haben, wenn sie
          irgendwann anders Urlaub genommen haben.
          Was ich also bräuchte währe theoretisch ein select auf urlaub, das den
          namen zurück gibt und das datum des current_date, wenn er vorhanden ist.
          Dieses select muß mit der tabelle namen gejoint werden und darauf ein
          select wo nur die namen angezeigt werden, an denen urlaubdatum nicht
          current_date ist.

          Nach dem dritten durchlesen dann schon. Das hatte ich völlig übersehen.
          Was jetzt folgt, ist eine Lösung, die funktionieren sollte (ich kanns hier
          nicht testen), aber hässlich ist und auch nicht empfohlen.
          http://www.mysql.com/doc/J/O/JOIN.html

          Nur, die einzige andere Lösung die du hast, sind SubQueries oder komplizierte
          Zwischentabellendinger, und die sind auch nicht als schön zu bezeichnen.

          select *
            from namen
             left join aerzte
                  on (namen.name = aerzte.arzt)
             left join urlaub
                  on (urlaub.urlaubname = namen.name
                      and urlaub != current_date
                      and (Raum != '1.Dienst' or Raum != '2.Dienst' or Raum != 'FOÄ'))

          Wie gesagt, ungetestet, wenns nicht funktioniert, bitte posten
          dann kann ichs heute abend genauer anschauen mit mehr Zeit und
          Literatur.

          Gruss Daniela

          1. Hallo Daniele

            Erstmal DANKE für die Antwort und vor allem *verwunderung* das Du in so alten Beitrag nochmal schaust, ob sie das überhaupt geklärt hat...

            Die Syntax hat (nach ein paar Ergänzungen, man muß ja die Quelle angeben, woher die Spalte kommt z.B. aerzte.Raum, das aber nur nebenbei) die Tabelle ausgegeben, bis auf die Zeilen, an denen urlaubdatum != current_date ist :-(

            Ich finde es komisch, daß im MySQL-Handbuch steht, das man bestimmte Sachen nicht benutzen sollte, weil sie unschön sind, aber keine bessere Lösung vorschlagen.

            Also, danke
                     Graphity

            1. Hallo Daniele

              Oops, Du heißt ja DanielA, entschuldigung

            2. Hi Graphity

              Erstmal DANKE für die Antwort und vor allem *verwunderung* das Du in so alten Beitrag nochmal schaust, ob sie das überhaupt geklärt hat...

              Ich verfolge Threads in denen ich was geschrieben habe immer bis sie
              verschwinden, ausser der Autor sagt, danke, hat das Problem gelöst.
              (Und wenn er das nicht sagt wenns gelöst ist, ärgere ich mich auch
              darüber.)

              Die Syntax hat (nach ein paar Ergänzungen, man muß ja die Quelle angeben, woher die Spalte kommt z.B. aerzte.Raum, das aber nur nebenbei) die Tabelle ausgegeben, bis auf die Zeilen, an denen urlaubdatum != current_date ist :-(

              Ist das jetzt das was du wolltest (wegen dem unglücklichen smilie), oder fehlt noch was oder was falsch verstanden?

              Gruss Daniela

              1. Hallo Daniela

                Die Syntax hat (nach ein paar Ergänzungen, man muß ja die Quelle angeben, woher die Spalte kommt z.B. aerzte.Raum, das aber nur nebenbei) die Tabelle ausgegeben, bis auf die Zeilen, an denen urlaubdatum != current_date ist :-(

                Ist das jetzt das was du wolltest (wegen dem unglücklichen smilie), oder fehlt noch was oder was falsch verstanden?

                Vielleicht hab' ich's falsch erklärt, vielleicht hast Du's falsch verstanden...

                Ich wollte nicht, das die Zeile nicht angezeigt wird, wo urlaubdatum != current_date ist, sondern das ein Name, der an diesem Tag Urlaub hat überhaupt nicht angezeigt wird, auch nicht, wenn er an einem anderen Tag Urlaub genommen hat...

                Gruss Daniela

                Gruß
                   Graphity

                1. Hoi,

                  Ich wollte nicht, das die Zeile nicht angezeigt wird, wo
                  urlaubdatum != current_date ist, sondern das ein Name, der an
                  diesem Tag Urlaub hat überhaupt nicht angezeigt wird, auch nicht,
                  wenn er an einem anderen Tag Urlaub genommen hat...

                  Na, dann aendere das doch etwas ab:

                  select *
                    from namen
                     left join aerzte
                          on (namen.name = aerzte.arzt)
                     left join urlaub
                          on (urlaub.urlaubname = namen.name
                              and UNIX_TIMESTAMP(urlaub) <= UNIX_TIMESTAMP(current_date)
                              and (Raum != '1.Dienst' or Raum != '2.Dienst' or Raum != 'FOÄ'))

                  Das setzt allerdings vorraus, dass die, die keinen Urlaub haben, aus
                  der Urlaub-Spalte geloescht werden. Denn ich habe anscheinend
                  keinerlei Informationen darueber, wie lange derjenige Urlaub hat.

                  Gruesse,
                   CK