I would like to extract records with having an empty bookingId and get the maximum unbooked days back (from the first free day). The expected result should be:
Had a play with this. I might be missing something obvious but I can't see an easy way to do this with a single statement.
But I have come up with this nasty way of doing it.
SELECT z.baseid, z.bookingdate,
CASE
WHEN j.id IS NOT NULL THEN '11+ days free'
WHEN i.id IS NOT NULL THEN '10 days free'
WHEN h.id IS NOT NULL THEN '9 days free'
WHEN g.id IS NOT NULL THEN '8 days free'
WHEN f.id IS NOT NULL THEN '7 days free'
WHEN e.id IS NOT NULL THEN '6 days free'
WHEN d.id IS NOT NULL THEN '5 days free'
WHEN c.id IS NOT NULL THEN '4 days free'
WHEN b.id IS NOT NULL THEN '3 days free'
WHEN a.id IS NOT NULL THEN '2 days free'
ELSE '1 day free'
END AS DaysFree
FROM pricesbookings z
INNER JOIN pricesbookings y
ON z.baseid = y.baseid AND z.bookingid = 0 AND y.bookingid != 0 AND DATE_ADD(y.bookingdate, INTERVAL 1 DAY) = z.bookingdate
LEFT JOIN pricesbookings a ON z.baseid = a.baseid AND z.bookingid = 0 AND a.bookingid = 0 AND DATE_ADD(z.bookingdate, INTERVAL 1 DAY) = a.bookingdate
LEFT OUTER JOIN pricesbookings b ON a.baseid = b.baseid AND b.bookingid = 0 AND DATE_ADD(z.bookingdate, INTERVAL 2 DAY) = b.bookingdate
LEFT OUTER JOIN pricesbookings c ON b.baseid = c.baseid AND c.bookingid = 0 AND DATE_ADD(z.bookingdate, INTERVAL 3 DAY) = c.bookingdate
LEFT OUTER JOIN pricesbookings d ON c.baseid = d.baseid AND d.bookingid = 0 AND DATE_ADD(z.bookingdate, INTERVAL 4 DAY) = d.bookingdate
LEFT OUTER JOIN pricesbookings e ON d.baseid = e.baseid AND e.bookingid = 0 AND DATE_ADD(z.bookingdate, INTERVAL 5 DAY) = e.bookingdate
LEFT OUTER JOIN pricesbookings f ON e.baseid = f.baseid AND f.bookingid = 0 AND DATE_ADD(z.bookingdate, INTERVAL 6 DAY) = f.bookingdate
LEFT OUTER JOIN pricesbookings g ON f.baseid = g.baseid AND g.bookingid = 0 AND DATE_ADD(z.bookingdate, INTERVAL 7 DAY) = g.bookingdate
LEFT OUTER JOIN pricesbookings h ON g.baseid = h.baseid AND h.bookingid = 0 AND DATE_ADD(z.bookingdate, INTERVAL 8 DAY) = h.bookingdate
LEFT OUTER JOIN pricesbookings i ON h.baseid = i.baseid AND i.bookingid = 0 AND DATE_ADD(z.bookingdate, INTERVAL 9 DAY) = i.bookingdate
LEFT OUTER JOIN pricesbookings j ON i.baseid = j.baseid AND j.bookingid = 0 AND DATE_ADD(z.bookingdate, INTERVAL 10 DAY) = j.bookingdate
ORDER BY z.baseid, z.bookingdate
This only counts up to 11 or more days (easy to expand if you need to, but does need tha max number to be known in advance), and probably hideously inefficient.
Basically the table alias z is the first day, which is joined against table alias y to check that the previous day was booked. Then LEFT JOINs against a load more copies of the table each with an extra day added to the date. Then uses a CASE statement to check which is the largest one found to give you the number of days free.
Works, but your database might not appreciate it!