Announcement

Collapse
No announcement yet.

Alternative zu NOT EXISTS

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Alternative zu NOT EXISTS

    Hallo miteinander,

    ich habe eine Tabelle in der ich ich ein Objekt mit einen Datum verknüpfe. Ist das Objekt mit Datum in der Tabelle gespeichert, ist es an diesen Tag nicht verfügbar.
    Tabelle a
    [obj_id] [datum]
    1 2012-05-17
    1 2012-05-31

    Objekt-ID 1 ist am 17.05. und am 31.05.2012 nicht verfügbar.

    Wenn ich wissen will welche Objekte im Mai verfügbar sind frage ich wie folgt:

    SELECT obj.obj_id
    FROM obj
    WHERE NOT
    EXISTS (

    SELECT obj_id
    FROM a
    WHERE obj.obj_id = a.obj_id
    AND datum >= '2012-05-01'
    AND datum <= '2012-05-31'
    )
    Alle Objekte die in der Tabelle a keinen Eintrag im Zeitraum haben werden angezeigt.

    Nun habe ich vor eine Abfrage zu schreiben in der ich Prüfen kann ob in den Zeitraum vom 01.05. bis 31.05.2012 ein Objekt sieben Tage am Stück verfügbar ist.

    Ich habe mir gedacht die Abfragen in der WHERE Klausel mit einer Schleife zu erzeugen, beginnend mit

    (NOT EXISTS (
    SELECT obj_id
    FROM a
    WHERE obj.obj_id = a.obj_id
    AND datum >= '2012-05-01'
    AND datum <= '2012-05-07'
    )

    und endend mit

    OR
    NOT EXISTS (
    SELECT obj_id
    FROM a
    WHERE obj.obj_id = a.obj_id
    AND datum >= '2012-05-25'
    AND datum <= '2012-05-31'
    ))

    würde dann so aussehen

    WHERE (NOT EXISTS(...) OR NOT EXISTS(...) usw.)

    Schaut natürlich nicht so Elegant aus wenn es in der Schleife 25 mal durchgelaufen ist.

    Meine Frage ist, ob es in MySQL eine andere und elegantere Möglichkeit gäbe.

  • #2
    Für mich ergeben Deine Erläuterungen und Beispiele nicht so richtig Sinn.
    Hast Du Dir mal angesehen, was "Exists" prüft?
    Oder sind hier Real World Begriffe mit technischen vermischt?
    Also z.B. ein Objekt (Hotelzimmer) ist zum Datum "verfügbar", wenn kein Buchungsdatensatz vorliegt (not exists)?
    Gruß, defo

    Comment


    • #3
      Originally posted by defo View Post
      Oder sind hier Real World Begriffe mit technischen vermischt?
      Also z.B. ein Objekt (Hotelzimmer) ist zum Datum "verfügbar", wenn kein Buchungsdatensatz vorliegt (not exists)?
      Genau darum geht es.

      Verfügbar wenn kein Buchungssatz vorhanden ist!

      Nun möchte ich Prüfen ob innerhalb eines Zeitraumes eine Menge an aneinanderliegende Tage verfügbar sind.

      Beispiel: Ist das Hotelzimmer im Zeitraum vom 01.05. bis 31.05.2012 14 Tage ununterbrochen verfügbar.

      Code:
      SELECT obj.obj_id
      FROM obj 
      WHERE 
      (
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-01' AND datum <= '2012-05-15')
      OR 
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-02' AND datum <= '2012-05-16')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-03' AND datum <= '2012-05-17')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-04' AND datum <= '2012-05-18')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-05' AND datum <= '2012-05-19')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-06' AND datum <= '2012-05-20')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-07' AND datum <= '2012-05-21')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-08' AND datum <= '2012-05-22')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-09' AND datum <= '2012-05-23')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-10' AND datum <= '2012-05-24')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-11' AND datum <= '2012-05-25')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-12' AND datum <= '2012-05-26')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-13' AND datum <= '2012-05-27')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-14' AND datum <= '2012-05-28')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-15' AND datum <= '2012-05-29')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-16' AND datum <= '2012-05-30')
      OR
      NOT EXISTS (SELECT obj_id FROM a WHERE obj.obj_id = a.obj_id AND datum >= '2012-05-17' AND datum <= '2012-05-31')
      )
      So funktioniert das auch. Ich prüfe beginnend am 01.05. ob 14 Tage ununterbrochen frei sind.

      Gibt es in MySQL eine Möglichkeit das zu kürzen?

      Comment


      • #4
        das ist ein sehr interessanter Anwendungsfall!
        Ich würde nach meinem Bauchgefühl dazu tendieren alle Objekte abzurufen, für die weniger Buchungen als Monatstage-gewünschte Buchungstage existieren (also mit count(*)-Subselect).
        Dann würde ich in dem verarbeitenden Programm die gebuchten Tage der Objekte durchgehen und prüfen ob 14tägige Lücken dazwischen sind.

        Rein mit SQL dürfte sich keine dynamische Lösung finden, soweit ich mich auskenne.

        Comment


        • #5
          Hallo,
          Originally posted by CLL View Post
          ...Rein mit SQL dürfte sich keine dynamische Lösung finden, soweit ich mich auskenne.
          Da SQL mengenorientiert arbeitet und Mengen keinen Nachfolger bzw. Vorgänger kennen, trifft dies prinzipiell zu. Bei MySQL kann man jedoch mit Systemvariablen etwas "tricksen"

          Ohne es bis ins Letzte und mit allen möglichen Kombinationen getestet zu haben, sollte folgendes Statement in MySQL funktionieren:

          [highlight=sql]
          set @myDate='2012-05-01';

          select freiVon, freiBis
          from (
          select id, @myDate freiVon, DATE_ADD(datum, INTERVAL -1 DAY) freiBis,
          DATEDIFF(datum, @myDate) daysbetween,
          @myDate:=DATE_ADD(datum, INTERVAL 1 DAY) nextDate
          from buchungen
          where datum between '2012-05-01' and '2012-05-31'
          union
          select null, @myDate, '2012-05-31',
          DATEDIFF('2012-05-31', @myDate),
          @myDate:='2012-05-31'
          order by 3) a
          where a.daysbetween >= 14
          [/highlight]

          Gruß Falk
          Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

          Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

          Comment


          • #6
            Danke für die Antwort.
            Mit den System variablen eröffnen sich mir ja ganz neue Möglichkeiten.

            Comment

            Working...
            X