/ / Wybierz porównywanie dat i rezerwacji w DB - mysql

Wybierz porównywanie dat i rezerwacji w DB - mysql

Mam bazę danych z items tabela i bookings stół. The bookings ma pozycję / wiersz dla każdego dnia, w którym przedmiot został zaksięgowany.

Muszę sprawdzić, które przedmioty nie są zarezerwowane w określonym przedziale czasu.

Próbuję uzyskać to za pomocą MySQL i próbowałem

SELECT * FROM items AS i
LEFT JOIN day_bookings AS db ON i.id = db.id_item
WHERE i.state <> 0
AND db.the_date NOT BETWEEN DATE("2016-02-01") AND DATE("2016-04-10")
GROUP BY i.id;

Daje mi to wszystkie przedmioty, bez odpowiedniego dopasowania terminów, jakich oczekiwałbym.

Mogłem to zrobić w kodzie po stronie serwera, coś jak:

Zaznacz wszystko db.the_date pomiędzy datami => zapętla wszystkie wiersze w wyniku i odfiltrowuje dopasowania.

Ale chciałbym go pobrać w MySQL. Wszelkie sugestie dotyczące tego, jak może wyglądać zapytanie?

Odpowiedzi:

1 dla odpowiedzi № 1

Wybierz wszystkie pozycje, które są zarezerwowane między datami, a następnie wklej je do podkwerendy NOT IN:

SELECT * FROM items WHERE id_item NOT IN
(SELECT id_item FROM day_bookings
WHERE the_date BETWEEN DATE("2016-02-01") AND DATE("2016-04-10"))

W zależności od wielkości tabel, o SELECT DISTINCT w zapytaniu zagnieżdżonym może, lub nie, przyspieszyć wykonanie.


1 dla odpowiedzi nr 2

Musisz sprawdzić na NULL wartość w db gdzie the_date jest w tym zakresie - jeśli element nie istnieje po prawej stronie lewego połączenia, wszystkie kolumny będą nim NULL.

Musisz również przenieść sprawdzenie daty do warunku łączenia, a nie do klauzuli WHERE, aby to działało.

SELECT * FROM items AS i
-- get bookings for the item between the required dates
LEFT JOIN day_bookings AS db ON i.id = db.id_item
AND db.the_date BETWEEN DATE("2016-02-01") AND DATE("2016-04-10")
WHERE i.state <> 0
AND db.id_item IS NULL -- only include if the booking does NOT exist