Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tsql 查找缺少的日期范围_Tsql_Sql Server 2000 - Fatal编程技术网

Tsql 查找缺少的日期范围

Tsql 查找缺少的日期范围,tsql,sql-server-2000,Tsql,Sql Server 2000,表1 code StartDate EndDate A 01/01/2011 06/15/2011 A 06/25/2011 06/30/2011 B 01/12/2011 07/31/2011 B 08/3/2011 12/31/2011 表2 code StartDate EndDate A

表1

code        StartDate        EndDate
A           01/01/2011        06/15/2011
A           06/25/2011        06/30/2011
B           01/12/2011        07/31/2011
B           08/3/2011         12/31/2011
表2

code        StartDate        EndDate
A           01/01/2011       06/30/2011
B           01/12/2011        07/31/2011
B           08/3/2011         12/25/2011
我需要找到表1中的内容,而不是表2中的内容

code        StartDate        EndDate
B           12/26/2011        12/31/2011
与表2和表1相反

code        StartDate        EndDate
A           06/16/2011       06/29/2011

日期字段中没有时间组件,最好使用T-SQL Server 2000。

这在SQL Server 2000中有点乏味。它使用数字表将日期范围扩展到各个行中。然后不存在反半联接,然后使用我从MSDN文章中偷来的孤岛方法再次将结果折叠回范围

SET DATEFORMAT MDY

DECLARE @Numbers TABLE (N INT PRIMARY KEY)

INSERT INTO @Numbers
SELECT number
FROM master..spt_values
WHERE type='P' AND number >= 0


DECLARE @Table1 TABLE
(
code CHAR(1),
StartDate DATETIME,
EndDate DATETIME
)
DECLARE @Table2 TABLE
(
code CHAR(1),
StartDate DATETIME,
EndDate DATETIME
)
INSERT INTO @Table1
SELECT 'A','01/01/2011','06/15/2011' UNION ALL
SELECT 'A','06/25/2011','06/30/2011' UNION ALL
SELECT 'B','01/12/2011','07/31/2011' UNION ALL
SELECT 'B','08/3/2011',' 12/31/2011'

INSERT INTO @Table2
SELECT 'A','01/01/2011','06/30/2011' UNION ALL
SELECT 'B','01/12/2011','07/31/2011' UNION ALL
SELECT 'B','08/3/2011',' 12/25/2011'

DECLARE @Results TABLE
(
code CHAR(1),
StartDate DATETIME
)

INSERT INTO @Results
SELECT T1.code,
       DATEADD(DAY, N, StartDate)
FROM   @Table1 T1
       INNER JOIN @Numbers N1
         ON N <= DATEDIFF(DAY, StartDate, EndDate)
WHERE  NOT EXISTS (SELECT *
                   FROM   @Table2 T2
                          INNER JOIN @Numbers N2
                            ON N2.N <= DATEDIFF(DAY, T2.StartDate, T2.EndDate)
                   WHERE  DATEADD(DAY, N1.N, T1.StartDate) =
                          DATEADD(DAY, N2.N, T2.StartDate)
                          AND T1.code = T2.code)  

/*SQL Server 2000 gaps and islands approach from here 
http://msdn.microsoft.com/en-us/library/aa175780%28v=sql.80%29.aspx*/
SELECT t1.code,
       t1.StartDate,
       MIN(t2.StartDate) AS EndDate
FROM   (SELECT StartDate,
               code
        FROM   @Results tbl1
        WHERE  NOT EXISTS(SELECT *
                          FROM   @Results tbl2
                          WHERE  tbl1.StartDate = tbl2.StartDate + 1
                                 AND tbl1.code = tbl2.code)) t1
       INNER JOIN (SELECT StartDate,
                          code
                   FROM   @Results tbl1
                   WHERE  NOT EXISTS(SELECT *
                                     FROM   @Results tbl2
                                     WHERE  tbl2.StartDate = tbl1.StartDate + 1
                                            AND tbl1.code = tbl2.code)) t2
         ON t1.StartDate <= t2.StartDate
         AND t1.code = t2.code
GROUP  BY t1.code,
          t1.StartDate  

这在SQLServer2000中有点乏味。它使用数字表将日期范围扩展到各个行中。然后不存在反半联接,然后使用我从MSDN文章中偷来的孤岛方法再次将结果折叠回范围

SET DATEFORMAT MDY

DECLARE @Numbers TABLE (N INT PRIMARY KEY)

INSERT INTO @Numbers
SELECT number
FROM master..spt_values
WHERE type='P' AND number >= 0


DECLARE @Table1 TABLE
(
code CHAR(1),
StartDate DATETIME,
EndDate DATETIME
)
DECLARE @Table2 TABLE
(
code CHAR(1),
StartDate DATETIME,
EndDate DATETIME
)
INSERT INTO @Table1
SELECT 'A','01/01/2011','06/15/2011' UNION ALL
SELECT 'A','06/25/2011','06/30/2011' UNION ALL
SELECT 'B','01/12/2011','07/31/2011' UNION ALL
SELECT 'B','08/3/2011',' 12/31/2011'

INSERT INTO @Table2
SELECT 'A','01/01/2011','06/30/2011' UNION ALL
SELECT 'B','01/12/2011','07/31/2011' UNION ALL
SELECT 'B','08/3/2011',' 12/25/2011'

DECLARE @Results TABLE
(
code CHAR(1),
StartDate DATETIME
)

INSERT INTO @Results
SELECT T1.code,
       DATEADD(DAY, N, StartDate)
FROM   @Table1 T1
       INNER JOIN @Numbers N1
         ON N <= DATEDIFF(DAY, StartDate, EndDate)
WHERE  NOT EXISTS (SELECT *
                   FROM   @Table2 T2
                          INNER JOIN @Numbers N2
                            ON N2.N <= DATEDIFF(DAY, T2.StartDate, T2.EndDate)
                   WHERE  DATEADD(DAY, N1.N, T1.StartDate) =
                          DATEADD(DAY, N2.N, T2.StartDate)
                          AND T1.code = T2.code)  

/*SQL Server 2000 gaps and islands approach from here 
http://msdn.microsoft.com/en-us/library/aa175780%28v=sql.80%29.aspx*/
SELECT t1.code,
       t1.StartDate,
       MIN(t2.StartDate) AS EndDate
FROM   (SELECT StartDate,
               code
        FROM   @Results tbl1
        WHERE  NOT EXISTS(SELECT *
                          FROM   @Results tbl2
                          WHERE  tbl1.StartDate = tbl2.StartDate + 1
                                 AND tbl1.code = tbl2.code)) t1
       INNER JOIN (SELECT StartDate,
                          code
                   FROM   @Results tbl1
                   WHERE  NOT EXISTS(SELECT *
                                     FROM   @Results tbl2
                                     WHERE  tbl2.StartDate = tbl1.StartDate + 1
                                            AND tbl1.code = tbl2.code)) t2
         ON t1.StartDate <= t2.StartDate
         AND t1.code = t2.code
GROUP  BY t1.code,
          t1.StartDate  

你试过什么?如果你想列出需求并获取代码,请雇佣一名顾问。我认为你的第二个必需结果集是错误的。两个表都有6/25->6/29的数据,所以A的范围应该是6/16->6/24。您尝试过什么?如果你想列出需求并获取代码,请雇佣一名顾问。我认为你的第二个必需结果集是错误的。两个表都有6/25->6/29的数据,所以A的范围应该是6/16->6/24。