在SQL中检查预订表上的可用性

时间:2009-06-24 10:17:09

标签: tsql

我正在编写一个职位空缺数据库,以获得一些乐趣(并尝试学习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智慧。

3 个答案:

答案 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

未经测试,但类似的东西可能有用。