Krånglig SQL, jämföra datum

Permalänk
Medlem

Krånglig SQL, jämföra datum

Hej hopp,

Detta är väl lite av en fortsättning på det problem jag ställde för några dagar sedan.

Jag har två datum som användaren har fyllt i i ett formulär, dessa ska sedan jämföras med databasen för att se att dem inte krockar med några datum som redan är inlagda.

Såhär ser dem aktuella kodraderna ut just nu:

$checkInDate = date('Ymd', mktime(0, 0, 0, $_POST['checkInMonth'], $_POST['checkInDay'], $_POST['checkInYear'])); $checkOutDate = date('Ymd', mktime(0, 0, 0, $_POST['checkOutMonth'], $_POST['checkOutDay'], $_POST['checkOutYear'])); $result = mysql_query("SELECT DISTINCT room_PK FROM rooms WHERE room_PK NOT IN (SELECT room_FK FROM bookings WHERE ('$checkInDate' BETWEEN checkInDate AND checkOutDate) OR ('$checkOutDate' BETWEEN checkInDate AND checkOutDate))"); while($row = mysql_fetch_array($result)) { echo "" . $row['room_PK'] . "<br />"; }

Det är ett hotellbokningssystem, och datumen som användaren fyller i är dem dagar han/hon vill bo på hotellet. Dessa skall sedan jämföras mot existerande bokningar så att en lista över lediga rum kan visas. Denna lista skapas genom att visa alla dem rum där dem existerande in- och utcheckningsdatumen inte krockar med de datum användaren fyllt i.

Jag tänkte då att det vore enkelt att bara jämföra med between, först med det angivna incheckningsdatumet och ta fram dem rum där det inte ligger inuti den existerande bokningen, och sen en till between men för det angivna utcheckningsdatumet.

Jag är mycket osäker på SQL-satsen, det kanske inte går att köra två stycken between-jämförelser på detta sätt?
Finns det kanske något enklare sätt?

Visa signatur

|| Intel 8700K || MSI GTX 1080 TI Gaming X || Xonar DG || Samsung 750 EVO 500GB & Kingston A2000 1TB & Samsung 960 EVO 250GB || XFX XXX 650W || Antec P183 || Asus G-Sync RoG Swift PG279Q || Dell XPS 15 || Thinkpad X220

The Force is like Duct Tape, it has a light side, a dark side, and holds the universe together.

Permalänk
Medlem
Skrivet av Newklear:

Hej hopp,

Detta är väl lite av en fortsättning på det problem jag ställde för några dagar sedan.

Jag har två datum som användaren har fyllt i i ett formulär, dessa ska sedan jämföras med databasen för att se att dem inte krockar med några datum som redan är inlagda.

Såhär ser dem aktuella kodraderna ut just nu:

$checkInDate = date('Ymd', mktime(0, 0, 0, $_POST['checkInMonth'], $_POST['checkInDay'], $_POST['checkInYear'])); $checkOutDate = date('Ymd', mktime(0, 0, 0, $_POST['checkOutMonth'], $_POST['checkOutDay'], $_POST['checkOutYear'])); $result = mysql_query("SELECT DISTINCT room_PK FROM rooms WHERE room_PK NOT IN (SELECT room_FK FROM bookings WHERE ('$checkInDate' BETWEEN checkInDate AND checkOutDate) OR ('$checkOutDate' BETWEEN checkInDate AND checkOutDate))"); while($row = mysql_fetch_array($result)) { echo "" . $row['room_PK'] . "<br />"; }

Det är ett hotellbokningssystem, och datumen som användaren fyller i är dem dagar han/hon vill bo på hotellet. Dessa skall sedan jämföras mot existerande bokningar så att en lista över lediga rum kan visas. Denna lista skapas genom att visa alla dem rum där dem existerande in- och utcheckningsdatumen inte krockar med de datum användaren fyllt i.

Jag tänkte då att det vore enkelt att bara jämföra med between, först med det angivna incheckningsdatumet och ta fram dem rum där det inte ligger inuti den existerande bokningen, och sen en till between men för det angivna utcheckningsdatumet.

Jag är mycket osäker på SQL-satsen, det kanske inte går att köra två stycken between-jämförelser på detta sätt?
Finns det kanske något enklare sätt?

Det enklaste är ju att du sätter upp bra testbokningar; före, efter, mitt i, före checkin till efter checkin, före checkout till efter checkout.

Säg att man vill boka från den 5:e till den 10:e
Din query fungerar exempelvis om det redan finns en bokning mellan den 3:e och 6:e ("före checkin till efter checkin").
Den fungerar inte om det finns en bokning exempelvis mellan 7:e och 8:e ("mitt i"-fallet)

Om du vänder på steken:

SELECT DISTINCT room_PK FROM rooms WHERE room_PK NOT IN ( SELECT room_FK FROM bookings WHERE (checkInDate BETWEEN '$checkInDate' AND '$checkOutDate') OR (checkOutDate BETWEEN '$checkInDate' AND '$checkOutDate') )

Denna query kontrollerar om en befintlig boknings checkin eller checkout finns (eftersom vi vill ha denna krock i queryn) i de sökta tiderna.
Denna bör även ta "mitt i"-fallet... men jag kan inte garantera det, eftersom jag inte kan testa det så bra.

Som sagt, sätt upp testbokningar så ser du nog hur du löser detta bäst.

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?