如何使用 between 子句过滤掉 2 个不同的日期时间字段

How can I use between clause to filter out 2 different datetime fields

我需要实施大厅预订系统,并且需要根据预订的 FromDateTimeToDateTime

获得免费大厅

订单Table

HallID       FromDateTime            ToDateTime
1        2018-01-01 03:00:00    2018-01-01 05:00:00
2        2018-01-01 06:30:00    2018-01-01 12:00:00
3        2018-01-01 13:00:00    2018-01-01 15:15:00

用户应该可以输入FromDateTimeToDateTime来查看订单table中是否有记录。如果存在则大厅不可预订。

测试场景:输入

    FromDateTime           ToDateTime           Result
2018-01-01 03:00:00    2018-01-01 05:00:00 : Hall not available
2018-01-01 08:45:00    2018-01-01 10:30:00 : Hall not available (This time is between Hall ID 2s booking time)
2018-01-01 15:30:00    2018-01-01 18:00:00 : Hall available

问题

在这种情况下,FromDateTimeToDateTime中的between子句是否可以解决这个问题? 我找不到使用 between 的方法,所以我使用了以下方法。但是它的成本很高。

-- Selecting all the records related to perticular product(hall) in to a temp table.

DECLARE @TempOrderDateTime TABLE (FromDateTime DATETIME,ToDateTime DATETIME)
INSERT INTO @TempOrderDateTime
SELECT FromDateTime,ToDateTime
FROM [Order].[Order]
WHERE ProductID = 7

将每条记录拆分为 1 小时的药水并存储在临时 table 中。这会产生另一个问题。

问题是如果我使用 1 小时段算法将无法处理在 FromDateTime 或 ToDateTime 中有分钟数的记录

DECLARE @ProdTimes TABLE (Dates DATETIME)
DECLARE @PRowCount INT = (SELECT COUNT(*) FROM @TempOrderDateTime)
WHILE(@PRowCount>0)
BEGIN
DECLARE @TopFromDateTime DATETIME = (SELECT TOP(1)FromDateTime FROM 
@TempOrderDateTime)
DECLARE @TopToDateTime DATETIME = (SELECT TOP(1)ToDateTime FROM @TempOrderDateTime)    
;WITH Dates_CTE 
     AS (SELECT @TopFromDateTime AS Dates
         UNION ALL
         SELECT DATEADD(HOUR, 1, Dates)
         FROM   Dates_CTE
         WHERE  Dates < @TopToDateTime)
INSERT INTO @ProdTimes
SELECT Dates
FROM   Dates_CTE AS t
OPTION (MAXRECURSION 0);
         DELETE TOP(1) FROM @TempOrderDateTime 
         SET @PRowCount = (SELECT COUNT(*) FROM @TempOrderDateTime)
END

这里我将 FromDateTime 和 ToDateTime 作为输入以检查可用性。

DECLARE @FromDateTime DATETIME  = '2018-06-01 12:00:00.000'
DECLARE @ToDateTime DATETIME = '2018-06-01 14:00:00.000'
DECLARE @PTimes TABLE (Dates DateTime)  

;WITH Dates_CTE
     AS (SELECT @FromDateTime AS Dates
         UNION ALL
         SELECT DATEADD(HOUR, 1, Dates)
         FROM   Dates_CTE
         WHERE  Dates < @ToDateTime)
INSERT INTO @PTimes
SELECT *
FROM   Dates_CTE AS t
OPTION (MAXRECURSION 0);

DELETE FROM @PTimes WHERE Dates = @FromDateTime OR Dates = @ToDateTime

最后执行以下操作以匹配 tables。如无记录,可预约展厅

SELECT * FROM @PTimes p
WHERE EXISTS (SELECT 1 FROM @ProdTimes pt WHERE p.Dates = pt.Dates)

我的方法目前适用。但主要缺点是

请建议我一个正确的方法来处理这个问题。

提前致谢。

我希望我明白了,但如果没有,请随时发表评论。
假设用户将在 2018-01-01-04:30:00

提交请求

日期Table:

   FromDateTime           ToDateTime           Result
2018-01-01 03:00:00    2018-01-01 05:00:00 : Hall not available
2018-01-01 08:45:00    2018-01-01 10:30:00 : Hall not available (This time is between Hall ID 2s booking time)
2018-01-01 15:30:00    2018-01-01 18:00:00 : Hall available

您的支票应该是这样的:

DECLARE @UserDateRequest DATETIME = '2018-01-01-04:30:00'
SELECT @UserDateRequest,
       Result
FROM DATES
WHERE @UserDateRequests BETWEEN @FromDateTime AND @ToDateTime

你不想要 between。逻辑是:

select h.*
from halls h
where not exists (select 1
                  from orders o
                  where o.hallid = h.hallid and
                        o.FromDateTime < @ToDateTime and
                        o.ToDateTime > @FromDateTime
                 );

我很确定这是解决您的问题的最简单方法。请注意,重叠的定义根本不涉及 between。如果一个时段在第二个结束之前开始并在第二个开始之后结束,则两个时段重叠。