admin

间隔表中的间隔

sql

我有两列这样的表:

+-----------+------------+
|   FROM    |     TO     |
+-----------+------------+
|2015-03-01 | 2015-03-04 |
|2015-03-05 | 2015-03-09 |
+-----------+------------+

我想编写一个带有两个参数的函数-DateFrom和DateTo,并检查此间隔。例如,如果函数采用DateFrom = 2015-03-03,并将其DateTo = 2015-03-08作为参数,则应返回true,因为该间隔中的每一天都在表中。

但是如果表是这样的:

+-----------+------------+
|   FROM    |     TO     |
+-----------+------------+
|2015-03-01 | 2015-03-04 |
|2015-03-06 | 2015-03-09 |
+-----------+------------+

该函数应该返回false,因为2015-03-05它不在表中。对算法有任何想法吗?谢谢你的帮助。


阅读 216

收藏
2021-06-07

共1个答案

admin

如果您还没有日历表,则可以使用计数表:

DECLARE @t TABLE
    (
      FromDate DATE ,
      ToDate DATE
    )

INSERT  INTO @t
VALUES  ( '2015-03-01', '2015-03-04' ),
        ( '2015-03-05', '2015-03-09' )

DECLARE @from DATE =  '2015-03-03', @to DATE = '2015-03-08'

;WITH cte1 AS(SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS d
             FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n)
             CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
             CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)),
      cte2 AS(SELECT DATEADD(dd, d - 1, @from) AS d 
              FROM cte1 
              WHERE DATEADD(dd, d - 1, @from) <= @to)

SELECT  CASE WHEN EXISTS ( SELECT *
                           FROM cte2
                           WHERE NOT EXISTS ( SELECT *
                                              FROM   @t t
                                              WHERE  d BETWEEN t.FromDate AND t.ToDate ) )
             THEN 0
             ELSE 1
        END AS IntervalExists

它将以间隔1000天的间隔工作。如果需要更多,则添加更多cross joins(一个cross join将间隔乘以10)。

2021-06-07