Zur Startseite Zum besseren Verständnis, hier nochmal der Code für die Abfrage der belegten Zimmer:
$sql = "SELECT nummer, status, name,
anreise, abreise FROM zimmer
where
('$anreise' BETWEEN date_add(anreise, INTERVAL 1 DAY)
AND DATE_ADD(abreise, INTERVAL -1 DAY))
OR
('$abreise' BETWEEN DATE_ADD(anreise, INTERVAL 1 DAY)
AND DATE_ADD(abreise, INTERVAL -1 DAY))
OR
(
('$anreise' <= anreise) AND
('$abreise' >= abreise)
)
GROUP BY nummer";
Obwohl nur die Zimmernummer interessiert, werden zusätzliche Felder wie status und name mit ausgegeben, um das Ergebnis anschaulicher zu machen. Diese Felder können im zweiten Schritt wieder entfernt werden.

Es wurden zwei Reservierungen für Schmidt und Müller eingegeben. Schmidt reist am Tag 4 an und am Tag 7 wieder ab. Müller kommt am Tag 2 und geht am Tag 5. Für die Abfrage wurde ein Zeitraum von Tag 1-4 und 2-9 gewählt.
Die erste Abfrage muss in jedem Fall das von Müller reservierte Zimmer als belegt zeigen. Bei Schmidt gibt es einen Grenzfall: Was passiert wenn ein Gast am gleichen Tag eintrifft, an dem der andere Gast abreist? Da die Gäste üblicherweise bis 11 Uhr abreisen und neue Gäste nicht vor 16 Uhr eintreffen, dürfen sich An- und Abreisetag auch überschneiden. Das Zimmer von Schmidt sollte also als frei angezeigt werden.
Der erste Teil der Abfrage prüft genau diesen Umstand:
('$anreise' BETWEEN
date_add(anreise, INTERVAL 1 DAY)
AND DATE_ADD(abreise, INTERVAL -1 DAY))
Dieser Teil testet, ob der gefrage Anreisetag im Bereich zwischen (BETWEEN) einem schon reservierten Anreisetag + 1 Tag und einem reservierten Abreisetag - 1 Tag liegt. Da die Bedingung BETWEEN auch auf Gleichheit prüft, muss der jeweilige Anreise- und Abreisetag um einen Tag erhöht bzw. vermindert werden. Dazu eignet sich die SQL-Funktion DATE_ADD, mit dem jeweiligen INTERVAL von +1 DAY bzw. -1 DAY.
Wird beim Anreisetag keine Überschneidung mit einer bestehenden Reservierung gefunden, so muss jetzt noch der Abreisetag geprüft werden:
OR
('$abreise' BETWEEN
DATE_ADD(anreise, INTERVAL 1 DAY)
AND DATE_ADD(abreise, INTERVAL -1 DAY))
Die Abfrage ist identisch mit der eben beschriebenen, nur auf den Abreisetag bezogen. Die beiden Abfragen müssen mit OR verknüpft werden, denn wenn nur eine von beiden Bedingungen wahr ist, ist das Zimmer belegt.
Diese kombinierte Bedingung wäre ausreichend für Anfrage 1. Wird hingegen Anfrage 2 mit dieser Bedingung geprüft, so wird das für Schmidt reservierte Zimmer nicht gefunden. Das liegt einfach daran, dass hier weder der Anreisetag, noch der Abreisetag innerhalb einer reservierten Periode liegt. Stattdessen liegt die von Schmidt reservierte Periode vollständig innerhalb des abgefragten Zeitbereiches.
Um diese Bedingung auch noch zu erfassen, muss die Abfrage um eine weitere Bedingung ergänzt werden:
OR
(
('$anreise' < anreise) AND
('$abreise' > abreise)
)
Hier wird nun speziell der Fall geprüft, dass eine Reservierung innerhalb des abgefragten Bereichs liegt. Auch diese Teilbedingung muss mit OR verknüpft werden.
Nachdem die belegten Zimmer ermittelt wurden, können die freien Zimmer durch eine Ausschluss-Suche festgestellt werden. Hierfür werden jetzt die Anfangs angelegten "Dummy-Zimmer" abgefragt. Eine entsprechende SQL-Anweisung lautet dann beispielsweise:
select nummer from zimmer where status='frei' and nummer not in (5,8)
Wobei die Zimmer 5 und 8 als belegt ermittelt wurden. Diese SQL-Anweisung wird in dem obigen Beispiel als dem Ergebnis der ersten Abfrage zusammengesetzt. Dabei muss man lediglich darauf achten, dass am Ende eine Syntaktisch korrekte SQL-Anweisung herauskommt. Für diesen Zweck wurden einige String-Funktionen aus PHP verwendet. Das Resultat ist eine Ergebnissmenge mit allen verfügbaren Zimmern.
