Return rows which don't have any matches in multiple-join situation
I must admit I'm pretty bad when it comes to SQL (MySQL in this case) so I apologise if this is simple!
I have the following query:
SELECT b.tourrefcode, t.startdate, SUM(a.adults + a.children + a.infants) as Pax FROM
explorer.booking_record b
INNER JOIN explorer.bookingroom a ON a.bookingref = 开发者_如何转开发b.bookingref
LEFT JOIN explorer.tour t ON b.tourrefcode = t.tourcode AND (t.startdate > '2012-02-01' AND t.startdate < '2012-03-01') AND (b.bookingstatus = "P" OR b.bookingstatus = "F") AND (b.tourdeparturedate > '2012-02-01' AND b.tourdeparturedate < '2012-03-01')
GROUP BY t.tourcode
HAVING SUM(a.adults + a.children + a.infants) < 120
The idea is that the query returns every tour from explorer.tour along with a count of the passengers (Pax in this case) for every booking found in booking_record. Booking_record is linked to bookingroom which contains the adults/children/infant figures.
As such, I'm having to join booking_reference with bookingroom to get the figures I'm looking for.
The query itself works perfectly and gives me the correct passengers for the correct tour on the correct date. However, it will not show me those tours in which there have been no bookings.
I've tried a number of different constructions of the same query including every type of join and moving the clauses from WHERE into the ON (as shown in the current implementation).
Any help would be massively appreciated!
EXPLAIN as requested:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t index PRIMARY 11 58415 Using index; Using temporary; Using filesort
1 SIMPLE a ALL PRIMARY 718736
1 SIMPLE b eq_ref PRIMARY PRIMARY 5 explorer.a.bookingref 1
Regards, Daniel.
You are mixing up your left/right joins:
SELECT b.tourrefcode, t.startdate, SUM(a.adults + a.children + a.infants) as Pax FROM
explorer.booking_record b
INNER JOIN explorer.bookingroom a ON a.bookingref = b.bookingref
RIGHT JOIN explorer.tour t ON b.tourrefcode = t.tourcode AND (t.startdate > '2012-02-01' AND t.startdate < '2012-03-01') AND (b.bookingstatus = "P" OR b.bookingstatus = "F") AND (b.tourdeparturedate > '2012-02-01' AND b.tourdeparturedate < '2012-03-01')
GROUP BY t.tourcode
HAVING SUM(a.adults + a.children + a.infants) < 120
I changed one join to a RIGHT JOIN.
精彩评论