首页 > 解决方案 > 获取未在 T-SQL 中保留的位置

问题描述

我有我的地方(eventos_espacios)的表格,其中有列:

idPlace, name, minCapacity, maxCapacity, and cleaningTime

我有预订表(eventos_evento_reservacion),我有:

idReservation, idPlace, startDate, endDate, and wantedCapacity

这是我的示例数据:

DECLARE @eventos_espacios TABLE (idPlace INT, name varchar(20), minCapacity INT, maxCapacity INT, cleaningTime INT)
INSERT INTO @eventos_espacios
SELECT 1, 'Conference Room', 20, 50, 120

SELECT *
    FROM @eventos_espacios

DECLARE @reservations  TABLE (idReservation INT, idPlace INT, startDate datetime, endDate datetime, wantedCapacity INT)
INSERT INTO @reservations
select 1, 1, '2018-08-07 18:00','2018-08-07 21:00',45

SELECT *
    FROM
    @reservations

F/E:我有一个活动,从今天 15 点到 17:30 进行。在 id = 1 的地方,清洁时间为 120 分钟。我真的很想从@eventos_espacios 中获取所有没有在@reservations 中保留的可用位置,并且考虑到已经保留的位置不包括cleaningTime,我可以在15 到19:30 之间使用。我有这样的东西,但似乎有些情况没有考虑,我不知道为什么。

SELECT DISTINCT
ee.idPlace,
ee.name
FROM @reservations eer
INNER JOIN @eventos_espacios ee on ee.idPlace = eer.idPlace
WHERE 30 between ee.minCapacity and ee.maxCapacity
AND ee.idPlace NOT IN
(
    SELECT DISTINCT
    ee.idPlace
    FROM @reservations eer
    INNER JOIN @eventos_espacios ee on ee.idPlace = eer.idPlace    
    WHERE ( 
                ( '2018-08-07 15:00' >= startDate AND '2018-08-07 17:30' <= DATEADD(MINUTE,ee.cleaningTime,endDate)) or 
                ( '2018-08-07 17:30' > startDate AND '2018-08-07 17:30' < DATEADD(MINUTE,ee.cleaningTime,endDate)) or 
                ( '2018-08-07 15:00' > startDate AND '2018-08-07 15:00' < DATEADD(MINUTE,ee.cleaningTime,endDate)) or 
                ( '2018-08-07 15:00' < startDate AND '2018-08-07 17:30' > DATEADD(MINUTE,ee.cleaningTime,endDate)) or 
                ( startDate >= '2018-08-07 15:00' AND DATEADD(MINUTE,ee.cleaningTime,endDate) <= '2018-08-07 17:30') 
          )
)

这不应该返回下一个信息:

1   Conference Room 20  50  120

因为在 '2018-08-07 17:30' 中添加了 120 分钟的清洁时间,所以该地方将在 '2018-08-07 19:30' 之前免费,并且从 '2018-08-07 18' 开始已经有预订: 00' 到 '2018-08-07 21:00'。

从 '2018-08-07 21:00' 到 '2018-08-07 22:00' 的事件也会发生同样的情况,因为 idPlace = 1 的预订应考虑清洁时间,并且在 23 小时前应该是免费的。

提前致谢。

标签: sql-servertsql

解决方案


对此进行了尝试:

declare @start datetime = '2018-08-07 15:00'
declare @end datetime = '2018-08-07 17:30'
declare @capacity_needed int = 30

DECLARE @eventos_espacios TABLE (idPlace INT, name varchar(20), minCapacity INT, maxCapacity INT, cleaningTime INT)
INSERT INTO @eventos_espacios
SELECT 1, 'Conference Room 1', 20, 50, 120
union
SELECT 2, 'Conference Room 2', 20, 50, 15
union 
SELECT 3, 'Conference Room 3', 20, 50, 30
union 
SELECT 4, 'Conference Room 4', 20, 150, 180
union 
SELECT 5, 'Conference Room 5', 5, 20, 10

SELECT *
FROM @eventos_espacios

DECLARE @reservations  TABLE (idReservation INT, idPlace INT, startDate datetime, endDate datetime, wantedCapacity INT)
INSERT INTO @reservations
select 1, 1, '2018-08-07 18:00','2018-08-07 21:00',45
union all
select 1, 2, '2018-08-07 18:00','2018-08-07 21:00',30
union all
select 1, 3, '2018-08-07 18:00','2018-08-07 21:00',30
union all
select 1, 5, '2018-08-07 18:00','2018-08-07 21:00',15

SELECT *
FROM
@reservations

select e.*
from @eventos_espacios e left join @reservations r on r.idPlace = e.idPlace
where (r.startDate >= DATEADD(minute, e.cleaningtime,  @end)
or r.idReservation is null) and @capacity_needed between e.minCapacity and e.maxCapacity    

推荐阅读