检查范围之间的日期是否可用
Check if a date is available between ranges
我有一个部门租赁系统。因此用户可以租用一个部门,网站上不会提供日期。
所以我可以有一个部门,日期如下:
开始日期:'2022-04-11'
结束日期'2022-04-14'
和开始日期 '2022-04-16'
结束日期 '2022-04-18'
因此,如您所见,该部门有空 '2022-04-15'
我想要一个 select 声明 bit true or false
如果两个日期之间的日期可用,那么如果我的日期是
'2022-04-11'
和 '2022-04-18'
,它应该 return 一个真值,因为 '2022-04-15'
它是可用的。我怎样才能做到这一点?此致
您还需要生成 table 个日期 - 这样您的 DATES table 中每一天都有一行。
然后您可以使用外部联接将日期 table 加入主 table 并在主 table 端检查 NULLS 以进行验证。
-- Using your sample values, create a RENTAL table
CREATE TABLE Rentals (
RentalID INT IDENTITY(1,1),
StartDate DATE NOT NULL,
EndDate DATE NOT NULL
) ;
INSERT Rentals (StartDate, EndDate)
VALUES ('2022-04-11', '2022-04-14'), ('2022-04-16', '2022-04-18')
GO
-- Create the DATES table
CREATE TABLE DatesTable (
DateName DATE NOT NULL
);
GO
-- Populate it for this year
DECLARE @inc INT = 365
WHILE @inc > 0
BEGIN
INSERT DatesTable (DateName)
SELECT DATEADD(DAY, @inc, '2021-12-31') ;
SELECT @inc = @inc - 1 ;
END
GO
SELECT d.DateName, CASE WHEN r.StartDate IS NULL THEN 'TRUE' ELSE 'FALSE' END as IsAvailable
FROM DatesTable d
LEFT JOIN Rentals r ON d.DateName >= r.StartDate AND d.DateName <= r.EndDate
WHERE d.DateName BETWEEN '2022-04-11' and '2022-04-18'
ORDER BY d.[DateName] ASC
DepartmentTable:
name
start_date
end_date
parameter
@bookingDate
select count(*) from
Department
where @bookingDate between start_date and end_date
如果计数大于 0,则它不可用
我认为你可以使用 window 函数来实现你想要的。我不熟悉 SQL 服务器,但我用谷歌搜索,它似乎支持我的查询(我在 Postgres 中写的)。
create temporary table rentals (
id serial primary key,
starts_at date,
ends_at date
);
insert into rentals (starts_at, ends_at) values
('2022-01-05', '2022-01-6'),
('2022-01-08', '2022-01-14'),
('2022-01-15', '2022-01-16'),
('2022-01-18', '2022-01-20');
with r as (
select id,
starts_at,
ends_at,
lead(starts_at, 1) over(order by starts_at asc) as next_starts_at
from rentals
)
select
(
CASE count(id)
WHEN 0 THEN false
ELSE true
END
) as available
from r
where
( ends_at + interval '1 day' < next_starts_at OR next_starts_at IS NULL ) AND
ends_at >= '2022-01-03' AND
ends_at < '2022-01-05'
上面首先使用 window 函数 lead
创建了一个 CTE,以查找任何给定行的下一个开始日期。
select id,
starts_at,
ends_at,
lead(starts_at, 1) over(order by starts_at asc) as next_starts_at
from rentals
id | starts_at | ends_at | next_starts_at
----+------------+------------+----------------
1 | 2022-01-05 | 2022-01-06 | 2022-01-08
2 | 2022-01-08 | 2022-01-14 | 2022-01-15
3 | 2022-01-15 | 2022-01-16 | 2022-01-18
4 | 2022-01-18 | 2022-01-20 |
然后它会选择您想要的范围内的日期
ends_at >= '2022-01-03' AND
ends_at < '2022-01-05'
并且还会选择
的租金
- 他们的结束日期和下一次租赁的开始日期之间至少有一天的间隔
( ends_at + interval '1 day' < next_starts_at )
- 或者是系统中记录的最后一次租赁,因此在最后一次租赁之后肯定有空房
OR next_starts_at IS NULL
我在一系列日期对此进行了测试,假设我正确理解您的要求,它似乎可以正常工作。
我有一个部门租赁系统。因此用户可以租用一个部门,网站上不会提供日期。
所以我可以有一个部门,日期如下:
开始日期:'2022-04-11'
结束日期'2022-04-14'
和开始日期 '2022-04-16'
结束日期 '2022-04-18'
因此,如您所见,该部门有空 '2022-04-15'
我想要一个 select 声明 bit true or false
如果两个日期之间的日期可用,那么如果我的日期是
'2022-04-11'
和 '2022-04-18'
,它应该 return 一个真值,因为 '2022-04-15'
它是可用的。我怎样才能做到这一点?此致
您还需要生成 table 个日期 - 这样您的 DATES table 中每一天都有一行。
然后您可以使用外部联接将日期 table 加入主 table 并在主 table 端检查 NULLS 以进行验证。
-- Using your sample values, create a RENTAL table
CREATE TABLE Rentals (
RentalID INT IDENTITY(1,1),
StartDate DATE NOT NULL,
EndDate DATE NOT NULL
) ;
INSERT Rentals (StartDate, EndDate)
VALUES ('2022-04-11', '2022-04-14'), ('2022-04-16', '2022-04-18')
GO
-- Create the DATES table
CREATE TABLE DatesTable (
DateName DATE NOT NULL
);
GO
-- Populate it for this year
DECLARE @inc INT = 365
WHILE @inc > 0
BEGIN
INSERT DatesTable (DateName)
SELECT DATEADD(DAY, @inc, '2021-12-31') ;
SELECT @inc = @inc - 1 ;
END
GO
SELECT d.DateName, CASE WHEN r.StartDate IS NULL THEN 'TRUE' ELSE 'FALSE' END as IsAvailable
FROM DatesTable d
LEFT JOIN Rentals r ON d.DateName >= r.StartDate AND d.DateName <= r.EndDate
WHERE d.DateName BETWEEN '2022-04-11' and '2022-04-18'
ORDER BY d.[DateName] ASC
DepartmentTable:
name
start_date
end_date
parameter
@bookingDate
select count(*) from
Department
where @bookingDate between start_date and end_date
如果计数大于 0,则它不可用
我认为你可以使用 window 函数来实现你想要的。我不熟悉 SQL 服务器,但我用谷歌搜索,它似乎支持我的查询(我在 Postgres 中写的)。
create temporary table rentals (
id serial primary key,
starts_at date,
ends_at date
);
insert into rentals (starts_at, ends_at) values
('2022-01-05', '2022-01-6'),
('2022-01-08', '2022-01-14'),
('2022-01-15', '2022-01-16'),
('2022-01-18', '2022-01-20');
with r as (
select id,
starts_at,
ends_at,
lead(starts_at, 1) over(order by starts_at asc) as next_starts_at
from rentals
)
select
(
CASE count(id)
WHEN 0 THEN false
ELSE true
END
) as available
from r
where
( ends_at + interval '1 day' < next_starts_at OR next_starts_at IS NULL ) AND
ends_at >= '2022-01-03' AND
ends_at < '2022-01-05'
上面首先使用 window 函数 lead
创建了一个 CTE,以查找任何给定行的下一个开始日期。
select id,
starts_at,
ends_at,
lead(starts_at, 1) over(order by starts_at asc) as next_starts_at
from rentals
id | starts_at | ends_at | next_starts_at
----+------------+------------+----------------
1 | 2022-01-05 | 2022-01-06 | 2022-01-08
2 | 2022-01-08 | 2022-01-14 | 2022-01-15
3 | 2022-01-15 | 2022-01-16 | 2022-01-18
4 | 2022-01-18 | 2022-01-20 |
然后它会选择您想要的范围内的日期
ends_at >= '2022-01-03' AND
ends_at < '2022-01-05'
并且还会选择
的租金- 他们的结束日期和下一次租赁的开始日期之间至少有一天的间隔
( ends_at + interval '1 day' < next_starts_at )
- 或者是系统中记录的最后一次租赁,因此在最后一次租赁之后肯定有空房
OR next_starts_at IS NULL
我在一系列日期对此进行了测试,假设我正确理解您的要求,它似乎可以正常工作。