Tables:
bookings: id, user_id, object_id, date1, …
booking_status: id, book_id, status
status is int, range from 1 to 9 (request, confirmed, paid, cancelled by user and that sort of stuff), so I need all bookings, where status is at least 4 (which means paid) but no value bigger than 4 (which would mean cancelled etc).
Till now the SELECT looks about like this (I left out some fields (…) to shorten it):
SELECT b.date1, ..., u.name FROM bookings b
LEFT JOIN user u ON (b.user_id = u.id)
LEFT JOIN booking_status bs ON (b.id=bs.book_id)
WHERE ((b.object_id=$object_id) AND (bs.status NOT IN (5,6,7,8,9)));"
…but it still selects those bookings that have booking status bigger than 4 as well. Any ideas how I need to change the query??
Thank you very much in advance!
UPDATE: thank you all again, I am amazed with how many great ideas you have come up with! There is really many ways to do it and I learned a lot from you, so thank you again! I will try all your suggestions and see for the performance, for now I mixed your solutions to this query, which works for now but I need to test it further:
SELECT b.date, ..., u.name FROM bookings b
LEFT JOIN user u ON (b.user_id = u.id)
LEFT JOIN booking_status bs ON (b.id=bs.book_id AND bs.status<=4)
WHERE (b.object_id=$object_id) HAVING MAX(bs.status)=4
it does not return multiple rows, but returns the rows with 4, excludes the rows with more than 4 and has no subqueries…
EDIT 2: I edited the query again… with HAVING MAX(bs.status)=4 it then works…
EDIT 3: sorry, after testing different cases I have to admit I was much too fast by saying it works…
inspired by ruakh’s solution without the correlated subqueries: