如何使用 between 子句过滤掉 2 个不同的日期时间字段
How can I use between clause to filter out 2 different datetime fields
我需要实施大厅预订系统,并且需要根据预订的 FromDateTime
到 ToDateTime
获得免费大厅
订单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
用户应该可以输入FromDateTime
到ToDateTime
来查看订单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
问题
在这种情况下,FromDateTime
和ToDateTime
中的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)
我的方法目前适用。但主要缺点是
- 如果订单 table 记录包含带有分钟的条目,算法将不起作用。因为它只过滤掉1小时的药水。
- 成本很高
请建议我一个正确的方法来处理这个问题。
提前致谢。
我希望我明白了,但如果没有,请随时发表评论。
假设用户将在 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
。如果一个时段在第二个结束之前开始并在第二个开始之后结束,则两个时段重叠。
我需要实施大厅预订系统,并且需要根据预订的 FromDateTime
到 ToDateTime
订单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
用户应该可以输入FromDateTime
到ToDateTime
来查看订单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
问题
在这种情况下,FromDateTime
和ToDateTime
中的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)
我的方法目前适用。但主要缺点是
- 如果订单 table 记录包含带有分钟的条目,算法将不起作用。因为它只过滤掉1小时的药水。
- 成本很高
请建议我一个正确的方法来处理这个问题。
提前致谢。
我希望我明白了,但如果没有,请随时发表评论。
假设用户将在 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
。如果一个时段在第二个结束之前开始并在第二个开始之后结束,则两个时段重叠。