Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [SQL] Wyświetlanie wolnych pokoi wg. terminarza
-coCCine-
post 1.10.2013, 18:18:34
Post #1





Goście







Cześć wszystkim!

Zastanawiam się w jaki sposób OPTYMALNIE zrealizować następujące założenie. Mamy tabelę gdzie trzymam spis pokoi, oraz tabele, w której trzymam informacje
nt. rezerwacji dla danego pokoju. Użytkownik przez formularz wysyła dwie daty (startową i końcową - od kiedy; do kiedy chce wynająć pokój) i teraz chciałbym pobrać listę pokoi (nazwa pokoju, opis pokoju, itd), gdzie rezerwacja będzie wolna - myślałem nad takim rozwiązaniem;

  1. # {CZAS_START} - unixtimestamp (np. 2013-10-01)
  2. # {KONIEC_CZASU} - unixtimestamp (np. 2013-10-08)
  3.  
  4. SELECT p.id AS pokoj_id, p.name, p.description FROM pokoje AS p
  5. WHERE p.id NOT IN(SELECT rez.hotel_pokoj_id FROM rezerwacje AS rez WHERE raz.start_rezerwacji >= {CZAS_START} AND raz.koniec_rezerwacji <= {KONIEC_CZASU})
  6. AND p.country_id = 'pl'


Struktura tabel wygląda mniej więcej tak:
  1. # pokoje
  2. id, name, description, country_id
  3.  
  4. # rezerwacje
  5. id, hotel_pokoj_id, start_rezerwacji, koniec_rezerwacji, dane_kontaktowe


Chciałbym Was prosić, czy dobrze jest zbudowana LOGIKA tego podzapytania - czy warunek WHERE ma sens ?
Go to the top of the page
+Quote Post
mmmmmmm
post 2.10.2013, 07:24:55
Post #2





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


Wszystko zależy od DBMS. MySQL średnio sobie poradzi z IN. Dla postgeSQL nie będzie to żadnym problemem.
Niemniej, ja bym to przerobił na inne zapytanie:
  1. SELECT p.id AS pokoj_id, p.name, p.description FROM pokoje AS p LEFT JOIN rezerwacje AS rez ON p.id=rez.hotel_pokoj_id AND rez.start_rezerwacji >= {CZAS_START} AND rez.koniec_rezerwacji <= {KONIEC_CZASU}
  2. WHERE p.country_id = 'pl' AND rez.hotel_pokoj_id IS NULL

Poza tym chyba masz parametry CZAS_START i KONIEC_CZASU na odwrót. Załóżmy taką sytuację:
CZAS_START: '2013-10-01'
KONIEC_CZASU: '2013-10-10'
rezerwacje:
1 '2013-10-01' '2013-10-07'
2 '2013-09-30' '2013-10-05'
3 '2013-09-30' '2013-10-12'
4 '2013-10-09' '2013-10-15'
Wg twojego zapytania tylko pokoj 1 'się załapie' jako zajęty. A tak nie jest - każdy z nich jest zajęty w tym okresie (choć w części). Zamień WHERE na rez.start_rezerwacji >= {KONIEC_CZASU} AND rez.koniec_rezerwacji <= {CZAS_START} i zobacz, co się stanie... smile.gif
Go to the top of the page
+Quote Post
Sephirus
post 2.10.2013, 09:41:34
Post #3





Grupa: Zarejestrowani
Postów: 1 527
Pomógł: 438
Dołączył: 28.06.2011
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Nie wchodząc w sprawy techniczne a algorytmiczne:

Jeśli mamy dwa zakresy dat, które nie mogą się w żaden sposób krzyżować to musisz sprawdzić sporo możliwych kombinacji.

Jeśli data startu planowanej rezerwacji zawiera się w okresie zajętości pokoju
lub
jeśli data końca planowanej rezerwacji zawiera się w okresie zajętości pokoju
lub
jeśli data startu zajętości pokoju zawiera się w okresie planowanej rezerwacji
lub
jeśli data końca zajętości pokoju zawiera się w okresie planowanej rezerwacji

to ten pokój powinien zostać wyeliminowany. Wystarczy to zanegować i użyć w zapytaniu by otrzymać listę pokoju które mogą być zarezerwowane smile.gif

  1.  
  2. NOT (
  3. rez.start_rezerwacji BETWEEN {CZAS_START} AND {KONIEC_CZASU}
  4. OR
  5. rez.koniec_rezerwacji BETWEEN {CZAS_START} AND {KONIEC_CZASU}
  6. OR
  7. {CZAS_START} BETWEENrez.start_rezerwacji AND rez.koniec_rezerwacji
  8. OR
  9. {KONIEC_CZASU} BETWEENrez.start_rezerwacji AND rez.koniec_rezerwacji
  10. )
  11.  


Ten post edytował Sephirus 2.10.2013, 09:42:48


--------------------
If you're good at something, never do it for free.
Potrzebujesz skryptu JS lub PHP - szukasz kogoś kto przetestuje twoją aplikację pod względem bezpieczeństwa? Szybko i solidnie? Napisz ;)
Mój blog - Jak zwiększyć wydajność front-endu - O buforowaniu wyjścia w PHP słów kilka...
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 29.05.2025 - 07:05