-
Construisez une liste de toutes les limites de réservation (c'est-à-dire les dates de début et de fin) qui se produisent dans la période souhaitée :
SELECT date_start AS boundary FROM bookings WHERE date_start BETWEEN @start AND @end UNION SELECT date_end FROM bookings WHERE date_end BETWEEN @start AND @end
-
Ajoutez à cela la frontière qui survient immédiatement avant la période souhaitée :
-- [ from part 1 above ] UNION SELECT MAX(boundary) FROM ( SELECT MAX(date_start) AS boundary FROM bookings WHERE date_start <= @start UNION ALL SELECT MAX(date_end) FROM bookings WHERE date_end <= @end ) t
-
Faites une jointure externe entre ce résultat et les
bookings
table, en gardant toutes les limites mais en n'incluant une réservation que si elle contribue au nombre de personnes simultanées après la limite :FROM bookings RIGHT JOIN ( -- [ from part 2 above ] ) t ON date_start <= boundary AND boundary < date_end
-
Additionnez le nombre de personnes à chaque limite :
SELECT IFNULL(SUM(quantity),0) AS simultaneous_people -- [ from part 3 above ] GROUP BY boundary
-
Trouvez le maximum et le minimum :
SELECT MIN(simultaneous_people), MAX(simultaneous_people) FROM ( -- [ from part 4 above ] ) t
Rassembler le tout :
SELECT MIN(simultaneous_people),
MAX(simultaneous_people)
FROM (
SELECT IFNULL(SUM(quantity),0) AS simultaneous_people
FROM bookings RIGHT JOIN (
SELECT date_start AS boundary
FROM bookings
WHERE date_start BETWEEN @start AND @end
UNION
SELECT date_end
FROM bookings
WHERE date_end BETWEEN @start AND @end
UNION
SELECT MAX(boundary)
FROM (
SELECT MAX(date_start) AS boundary
FROM bookings
WHERE date_start <= @start
UNION ALL
SELECT MAX(date_end)
FROM bookings
WHERE date_end <= @end
) t
) t ON date_start <= boundary AND boundary < date_end
GROUP BY boundary
) t
Voir sur sqlfiddle .