旅行者根据数据范围旅行- SQL



当我从提供时,我想返回当前正在旅行的所有旅行者和日期。意思是如果我从1 Jan 2022出发直到2022年1月10日我提供了一个From日期2022年1月5日日期2022年1月15日我必须回来,因为我在那段时间旅行。因此在下面的代码中,必须返回Mike。

DECLARE @DateFrom      DATE         = '2022-01-05',
@DateTo        DATE         = '2022-01-15'
DROP TABLE IF EXISTS #Dates
CREATE TABLE #Dates
(
DepartureDate  Date       NULL,
ReturnDate     Date       NULL,
Name           VARCHAR(8) NULL
)
INSERT INTO #Dates (DepartureDate, ReturnDate, Name)
VALUES ('2022-01-01', '2022-01-10', 'Mike' )
SELECT * 
FROM   #Dates
WHERE  DepartureDate >= @DateFrom
AND    ReturnDate    <= @DateTo

如果您选择的日期范围在'2021-12-01'和'2021-12-05'之间,则Mike没有旅行,因此不应返回。但是,如果您选择的日期范围在'2022-01-05'和'2022-01-15'之间,则应该返回Mike,因为Mike确实在该日期范围内旅行,即使他没有旅行所有的日子。

重叠区间问题!检查每个间隔是否在另一个间隔结束前开始:

SELECT * 
FROM   #Dates
WHERE  DepartureDate <= @DateTo
AND    ReturnDate    >= @DateFrom

我想你的问题是你的WHERE条款并不适用于所有情况来支持你的问题描述。

你可以这样写来修复它:

SELECT * 
FROM #Dates
WHERE  
(DepartureDate >= @DateFrom AND ReturnDate <= @DateTo) -- Traveled only between provided date range
OR (DepartureDate < @DateFrom AND ReturnDate > @DateTo) -- Traveled the entire date range, possibly longer 
OR (DepartureDate < @DateFrom AND ReturnDate <= @DateTo AND ReturnDate >= @DateFrom) -- Started traveling before date range but finished traveling within it 
OR (DepartureDate >= @DateFrom AND DepartureDate <= @DateTo AND ReturnDate > @DateTo) -- Started traveling within the date range but finished traveling after

请看每个案例的注释。

或者你也可以把它写成4个SELECT语句(每种情况一个)和一个UNION ALL子句。有时,SQL Server引擎在以这种方式编写查询时产生更有效的查询计划,而不是多个OR谓词:

-- Traveled only between provided date range
SELECT * 
FROM #Dates
WHERE  
DepartureDate >= @DateFrom 
AND ReturnDate <= @DateTo
UNION ALL
-- Traveled the entire date range, possibly longer
SELECT * 
FROM #Dates
WHERE 
DepartureDate < @DateFrom 
AND ReturnDate > @DateTo 

UNION ALL
-- Started traveling before date range but finished traveling within it 
SELECT * 
FROM #Dates
WHERE
DepartureDate < @DateFrom 
AND ReturnDate <= @DateTo
AND ReturnDate >= @DateFrom
UNION ALL
-- Started traveling within the date range but finished traveling after
SELECT * 
FROM #Dates
WHERE
DepartureDate >= @DateFrom 
AND DepartureDate <= @DateTo
AND ReturnDate > @DateTo

你必须测试两种方法,看看哪一种对你的特定情况表现更好。


旁注,不要使用SELECT *,因为它是一个反模式。相反,您应该显式地列出查询所需的列。

相关内容

  • 没有找到相关文章

最新更新