我有一张预订表:
预订可以重叠,因此例如可以同时进行20次预订。现在我想做两个查询:
1)检索给定时间段内的最大数量总和。
2)在给定时间段内检索最小数量总和。
我不知道如何将仅重叠预订的数量加在一起,而不是非重叠预订。任何帮助将不胜感激。
编辑:我为了清晰起见画了一张照片:http://i.imgur.com/8GDLV.png
答案 0 :(得分:2)
构建在所需期间内发生的所有预订边界(即开始和结束日期)的列表:
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
添加到所需时间段之前的边界:
-- [ 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
在此结果与bookings
表之间建立外部联接,保留所有边界,但仅包括预订,如果它有助于之后的同时人数边界:
FROM bookings RIGHT JOIN (
-- [ from part 2 above ]
) t ON date_start <= boundary AND boundary < date_end
总结每个边界的人数:
SELECT IFNULL(SUM(quantity),0) AS simultaneous_people
-- [ from part 3 above ]
GROUP BY boundary
找出最大值和最小值:
SELECT MIN(simultaneous_people),
MAX(simultaneous_people)
FROM (
-- [ from part 4 above ]
) t
全部放在一起:
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
在sqlfiddle上查看。
答案 1 :(得分:1)
在问题的给定数据结构中没有用于分组的字段。因此,假设您按ID
进行分组。
1)。要充分利用MAX
SELECT MAX(TotalQty) FROM
(
SELECT SUM(Quantity) AS TotalQty FROM Bookings
WHERE date_End<='<To Date>'
AND date_Start>='<From Date>'
GROUP BY id
) SumQty
2)。获得最大分钟MIN
SELECT MIN(TotalQty) FROM
(
SELECT SUM(Quantity) AS TotalQty FROM Bookings
WHERE date_End<='<To Date>'
AND date_Start>='<From Date>'
GROUP BY id
) SumQty