如何使用递归CTE确定可出租的背靠背用途

时间:2019-02-23 15:03:48

标签: sql sql-server database tsql

我正在研究一个过程,该过程将确定实体是否有足够的租赁设备来支付在指定时间内的所有租金。

我们还有一项新功能,允许客户在关闭地点的同时取回设备。

但是,我们还允许背对背出租,这意味着在实体关闭时,单个设备可以具有多个出租。

我需要一种方法来确定(假设所有租金均已提取并按时退还)是否有足够的设备来支付所有预订。

我尝试使用递归CTE来确定此值,但是我无法进一步推高我的最大递归限制,并且由于某些租借时间少于一个小时,因此我必须以30分钟为单位进行测量。

尽管这也是我第一次使用递归cte,所以我可能会犯一个错误。

我的示例如下:

ID              PickupTime                      DropOffTime
---     -------------------------------------    ------------------------------------
1    2019-2-28 23:00:00.000 2019-3-01 00:00:00.000
2    2019-3-01 00:00:00.000 2019-3-01 01:00:00.000
3    2019-3-01 04:00:00.000 2019-3-01 07:00:00.000
4    2019-2-28 22:00:00.000 2019-2-28 23:00:00.000
5    2019-2-2819:00:00.000  2019-2-28 21:00:00.000
6    2019-2-28 20:00:00.000 2019-2-28 22:00:00.000
7    2019-2-28 23:00:00.000 2019-3-01 01:00:00.000
8    2019-2-28 23:00:00.000 2019-3-01 01:00:00.000
9    2019-3-01 00:00:00.000 2019-3-01 02:00:00.000
10  2019-2-28 21:00:00.000  2019-2-28 22:00:00.000
11  2019-2-28 22:00:00.000  2019-2-28 23:00:00.000

And Equipment

ID    EquipmentNumber
--    ---------------
1     AB123
2     AC321
3     BL854

由于要在纸上找出答案,我知道至少需要4台设备才能覆盖这些设备。因此,如果可以保留所有保留,则应返回一个布尔值,说明是或否(在本例中为“否”)。

这是我尝试过的:

    DECLARE @MinprefDate DATETIME = (SELECT MIN(PreferredPickupDate) FROM #Results)
    DECLARE @MaxprefDate DATETIME = (SELECT MAX(PreferredPickupDate) FROM #Results)
    DECLARE @MinexpDate DATETIME = (SELECT MIN(ExpectedReceiveDate) FROM #Results)
    DECLARE @MaxexpDate DATETIME = (SELECT MAX(ExpectedReceiveDate) FROM #Results)

    ;WITH CTE AS (
                    SELECT 1 AS n, r.ID, r.ContractID, @MinprefDate AS PreferredPickupDate, @MinexpDate AS ExpectedReceiveDate, r.PreviousPickup, r.PreviousExpected, r.NextPickup, r.NextExpected 
                    FROM #Results r

                    UNION ALL

                    SELECT n + 1, ID, ContractID, DATEADD(MINUTE, 1, @MinprefDate), DATEADD(MINUTE, 1, @MaxexpDate), PreviousPickup, PreviousExpected, NextPickup, NextExpected FROM CTE
                    WHERE ExpectedReceiveDate <= @MaxexpDate
                    )
    SELECT * FROM CTE OPTION (MaxRecursion 3000)

1 个答案:

答案 0 :(得分:0)

如果我认为您的时间正在过去,那么01:00:00的确意味着25:00:00,那么我宁愿理解您的问题。

我不太确定如何处理领带,但是以下内容返回了您想要的:

select top (1) t.id, v.time, sum(inc) over (order by time, id) as overlaps
from t cross apply
     (values (pickuptime, 1), (dropofftime, -1)) v(time, inc)
order by overlaps desc;

Here是db <>小提琴。

无需使用递归CTE。您只需要考虑每个接送,就可以用累积的总和来完成。