我正在编写一个职位空缺数据库,以获得一些乐趣(并尝试学习T-SQL / SQL Server,这就是我目前在我的应用程序表中所拥有的。
application_id name interviewer location_id from to
-----------------------------------------------------------------------------------------------------------
1 Joe Bloggs Sarah Saunders 100 2008-12-25 00:00:00 2008-12-26 00:00:00
2 Barry White Issac Hayes 100 2008-12-29 00:00:00 2008-12-30 00:00:00
很容易找出为这些日期做出的预订;一个简单的选择语句可以很容易地找到它们。
我现在唯一的问题是如何弄清楚哪些日子不包含预订。我想在下表中搜索一下,在“2008-12-25 00:00:00”和“2008-12-30 00:00:00”之间查看location_id 100的房间可用日期并且回来说从27日到28日没有在房间里举行采访。
我确信这很容易,但请在我身上留下一些SQL智慧。
答案 0 :(得分:1)
您可以生成一个包含您的日期的临时表(在上层或使用存储的函数,如果用于SQL学习目的会更好),然后OUTER JOIN
在预订表上,过滤与NULL
匹配的application_id。
答案 1 :(得分:0)
首先,我首先将您的查询“2008-12-25 00:00:00”分解为“2008-12-30 00:00:00”,分别为每天一天的“时间段”。使用表变量和while循环相对容易,所以我不会在这里讨论它。
然后,您可以遍历表变量中的每个时间段,看看它是否与任何现有预订重叠(您只需提取与查询时间段重叠的预订)。为此,我建议使用这个辅助函数:
CREATE FUNCTION [dbo].[fn_TimePeriodsOverlap]
(
@pStartTP1 datetime,
@pEndTP1 datetime,
@pStartTP2 datetime,
@pEndTP2 datetime
)
RETURNS bit
AS
BEGIN
DECLARE @Result bit
SET @Result = 0
IF @pStartTP1 >= @pStartTP2 AND @pStartTP1 < @pEndTP2
SET @Result = 1
ELSE IF @pEndTP1 >= @pStartTP2 AND @pEndTP1 < @pEndTP2
SET @Result = 1
ELSE IF @pStartTP2 >= @pStartTP1 AND @pStartTP2 < @pEndTP1
SET @Result = 1
ELSE IF @pEndTP2 >= @pStartTP1 AND @pEndTP2 < @pEndTP1
SET @Result = 1
RETURN @Result
END
如果两个时间段重叠,则返回1,否则返回0。即使预订区块并非总是一整天,这也具有工作的优势。
答案 2 :(得分:0)
一种方法是将日期范围放在表变量中并加入。
declare @startDate datetime, @endDate datetime
SET @startDate = '2009-05-01'
SET @endDate = '2009-05-31'
declare @dates table (date datetime)
insert into @dates values (@startDate)
while @startDate < @endDate
begin
set @startDate = @startDate + 1
insert into @dates values (@startDate)
end
select d.* from applications a
left join @dates d on d.date between a.from and a.to
where a.application_id is null
未经测试,但类似的东西可能有用。