-
Sestavte seznam všech hranic rezervace (tj. data zahájení a ukončení), které se vyskytují v požadovaném období:
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
-
Přidejte k tomu hranici, která se vyskytuje bezprostředně před požadovaným obdobím:
-- [ 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
-
Proveďte vnější spojení mezi tímto výsledkem a
bookings
stůl, který zachovává všechny hranice, ale zahrnuje rezervaci pouze v případě, že přispívá k počtu současně probíhajících lidí po hranice:FROM bookings RIGHT JOIN ( -- [ from part 2 above ] ) t ON date_start <= boundary AND boundary < date_end
-
Sečtěte počet lidí na každé hranici:
SELECT IFNULL(SUM(quantity),0) AS simultaneous_people -- [ from part 3 above ] GROUP BY boundary
-
Najděte maximum a minimum:
SELECT MIN(simultaneous_people), MAX(simultaneous_people) FROM ( -- [ from part 4 above ] ) t
Dát to všechno dohromady:
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
Podívejte se na to na sqlfiddle .