假设您有一个100平方英尺的房间,并且您想在8月1日至8月31日期间租用它。 预订表架构
startdate|enddate|area|storageid
您有以下预订
06-Aug|25-Aug|50|'abc'
05-Aug|11-Aug|40|'xyz'
18-Aug|23-Aug|30|'pqr'
13-Aug|16-Aug|10|'qwe'
现在有人要求在8月8日至8月20日期间预订。对于这个日期范围,可用的最大面积是10平方英尺(因为,对于8月8日,10日和10月11日,只有10平方英尺可用。)
如何创建有效的SQL查询来获取此信息?现在我的查询非常混乱和低效,在某些情况下会产生错误的结果。我没有发布查询,因为它太乱了,我自己无法解释。
我不一定只想使用SQL来解决它。如果有一种算法可以有效地解决它,我会从数据库中提取所有数据。
答案 0 :(得分:0)
有人删除了SQL Server,但这是算法:
DECLARE @startDate date = '2016-08-09';
DECLARE @endDate date = '2016-08-20';
DECLARE @totalArea decimal(19,2) = 100;
WITH Src AS --Your source table
(
SELECT * FROM (VALUES
('2016-08-06', '2016-08-25', 50, 'abc'),
('2016-08-05', '2016-08-11', 40, 'xyz'),
('2016-08-18','2016-08-23',30,'pqr'),
('2016-08-13','2016-08-16',10,'qwe')
)T(startdate, enddate, area, storageid)
), Nums AS --Numbers table 0..N, N must be greater than ranges calculated
(
SELECT 0 N
UNION ALL
SELECT N+1 N FROM Nums
WHERE N<DATEDIFF(DAY,@startDate,@endDate)
) --Query
--You can use total-maxUsed from range of days
SELECT @totalArea-MAX(Used) FROM
(
--Group by day, sum all used areas
SELECT MidDate, SUM(Used) Used FROM
(
--Join table with numbers, split every day, if room used, return area
SELECT DATEADD(DAY, N, @startDate) MidDate, CASE WHEN DATEADD(DAY, N, @startDate) BETWEEN startDate AND endDate THEN area END Used
FROM Src
CROSS APPLY Nums
) T
GROUP BY MidDate
) T