2011-09-23 2 views
0

Tableau 1Trouvez les plages de la date manquante

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 

Tableau 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 

Je dois trouver ce qui est dans Table1 et non Tableau2 qui est

code  StartDate  EndDate 
B   12/26/2011  12/31/2011 

Et l'inverse de ce qui est dans le tableau 2 et non dans le tableau 1

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

Il n'y a aucun composant de temps dans le champ de date et T-SQL (SQL Server 2000) est préféré.

+1

Qu'avez-vous essayé? Si vous voulez lister les exigences et obtenir du code, engagez un consultant. – JNK

+0

Je pense que votre deuxième résultat requis est faux. Les deux tables ont des données de 6/25 à> 6/29, donc la plage pour A doit être 6/16 -> 6/24. –

Répondre

5

Cela est un peu fastidieux dans SQL Server 2000. Il utilise une table de nombres pour étendre les plages de dates dans des lignes individuelles. Puis NOT EXISTS pour l'anti semi-jointure puis utilise une approche "îles" que j'ai volé à partir d'un article MSDN pour replier le résultat dans des plages de nouveau.

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 
Questions connexes