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 № 1Wybierz 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