我正在为预订系统制作表格架构。预订可以持续数天或数小时。
例如:100台笔记本电脑可供使用,20人在不同日期租用35台笔记本电脑。有不同的登记和结账时间。
我想从结果中生成一个预订日历,显示每天有多少单位可用。
我正在尝试生成显示日期范围的单位数的结果,例如2016-01-01 10:30到2016-01-04 10:30。
Date | availableUnits
2016-01-01 | 10
2016-01-02 | 6
2016-01-03 | 0
2016-01-04 | 11
广告表
id | title | unit
142 | HP Laptop | 100
143 | Apple MacBook Air | 25
预订表
id | ad_id | start_date | end_date | units
5 | 143 | 2015-08-17 18:18:00 | 2015-08-24 18:18:00 | 5
8 | 142 | 2015-08-20 05:30:00 | 2015-08-31 05:30:00 | 2
1 | 143 | 2015-08-20 16:59:00 | 2015-08-25 16:58:00 | 1
6 | 142 | 2015-08-25 20:37:00 | 2015-08-29 20:37:00 | 1
10 | 142 | 2015-08-27 05:30:00 | 2015-08-29 04:30:00 | 1
11 | 143 | 2015-09-01 05:30:00 | 2015-09-05 05:30:00 | 3
4 | 142 | 2015-09-01 17:20:00 | 2015-10-12 17:20:00 | 2
3 | 143 | 2015-09-01 21:28:00 | 2015-09-30 21:28:00 | 5
19 | 143 | 2015-09-03 05:30:00 | 2015-09-26 05:30:00 | 1
12 | 142 | 2015-09-05 05:30:00 | 2015-09-10 05:30:00 | 1
如果有人喜欢运行查询,我创建了一个SQL小提琴。 SQL fiddle
我尝试过几种不同的方法但没有取得多大成功。存储每天的可用性是一种选择。但是,当广告数量增加时,这可能是一个大问题。如果我这样做,即使是少量广告也可以生成大量数据。
任何建议都是欢迎
答案 0 :(得分:0)
诀窍是使用每条记录,好像有2条记录。
在预订开始日期,这会对您的股票产生负面影响
SELECT b1.start_date at_date, -b1.units unitsDiff
FROM ad_bookings b1
在预订结束日期,您的股票再次上涨
SELECT b2.end_date at_date, b2.units unitsDiff
FROM ad_bookings b2
如果您想知道在特定时间有多少单位可用,您可以将这两个查询组合起来并按排序顺序求和:
-- availability at specific moment
SELECT grouped.at_date,
@sum := COALESCE(@sum,(SELECT unit FROM ads WHERE id = 142)) + grouped.unitsDiff CurrentTotal, grouped.unitsDiff
FROM (
SELECT sub.at_date, sum(sub.unitsDiff) unitsDiff
FROM (
SELECT b1.start_date at_date, -b1.units unitsDiff
FROM ad_bookings b1
WHERE b1.ad_id = 142
UNION
SELECT b2.end_date at_date, b2.units unitsDiff
FROM ad_bookings b2
WHERE b2.ad_id = 142
) sub
GROUP BY sub.at_date
) grouped
ORDER BY grouped.at_date
如果您想针对特定范围执行此操作,则只需要与该范围有任何重叠的ad_bookings
。
如果您想消除时间并具有特定日期,则可以投射开始日期和结束日期。 CAST(b1.start_date AS DATE) at_date
。 (你可能希望将你的end_date和你的start_date放在一起)
如果明确要求所有日期都在范围内,您可以添加虚拟记录,例如UNION '2015-10-22' at_date, 0 unitsDiff
我建议您查询所需的ad_bookings(可能已分组)并让应用程序逻辑处理它。但这取决于你。