2010-08-17 119 views
2

我有一張包含公司工作時間的表格。我們定義了範圍的日期範圍和小時數。 不在規定範圍內的工作小時數爲9.5小時。將缺失日期範圍添加到結果記錄集

我想要將9.5的值添加到結果記錄集的非定義範圍。 我該如何讓查詢得到這個結果?

表定義和添加的記錄:

IF OBJECT_ID ('dbo.tbl_WorkingHours') IS NOT NULL 
    DROP TABLE dbo.tbl_WorkingHours 
GO 

CREATE TABLE dbo.tbl_WorkingHours 
    (
    Startdate DATETIME NOT NULL, 
    EndDate  DATETIME NOT NULL, 
    HoursDefined FLOAT NULL, 
    Description VARCHAR (255) NULL, 
    PRIMARY KEY (Startdate,EndDate) 
    ) 

INSERT INTO dbo.tbl_WorkingHours 
    (Startdate,EndDate,HoursDefined,Description) 
VALUES 
    ('3/4/2010','3/29/2010',7,'') 
INSERT INTO dbo.tbl_WorkingHours 
    (Startdate,EndDate,HoursDefined,Description) 
VALUES 
    ('5/4/2010','5/29/2010',8,'') 

選擇的結果*:

Startdate | EndDate | HoursDefined | Description 
---------------------------------------------------- 
3/4/2010 3/29/2010 7 
5/4/2010 5/29/2010 8 

我想要的記錄集:

Startdate | EndDate | HoursDefined | Description 
---------------------------------------------------- 
1/1/1900 3/3/2010 9.5 
3/4/2010 3/29/2010 7 
3/30/2010 5/3/2010 9.5 
5/4/2010 5/29/2010 8 
5/30/2010 1/1/2050 9.5 

回答

0

下面的假設是不可能的具有重疊範圍或兩個定義的範圍,這些範圍是連續的,但是保持爲單獨的行。

WITH wh AS 
(

SELECT  Startdate, EndDate, HoursDefined, Description, 
     ROW_NUMBER() over (order by startdate) as rn 
FROM   tbl_WorkingHours 
) 
SELECT Startdate, EndDate, HoursDefined, Description 
FROM wh 
UNION ALL 
SELECT ISNULL(dateadd(day,1,w1.EndDate),'19000101'), 
     ISNULL(dateadd(day,-1,w2.StartDate),'20500101') , 9.5 AS HoursDefined,'' 
FROM wh w1 FULL OUTER JOIN wh w2 
ON w2.rn = w1.rn+1 
ORDER BY Startdate 
0

嘗試這樣:

DECLARE @tbl_WorkingHours table (Startdate DATETIME NOT NULL 
           ,EndDate  DATETIME NOT NULL 
           ,HoursDefined FLOAT NULL 
           ,Description VARCHAR (255) NULL 
           ,PRIMARY KEY (Startdate,EndDate) 
           ) 

INSERT INTO @tbl_WorkingHours (Startdate,EndDate,HoursDefined,Description) VALUES  ('3/4/2010','3/29/2010',7,'') 
INSERT INTO @tbl_WorkingHours (Startdate,EndDate,HoursDefined,Description) VALUES  ('5/4/2010','5/29/2010',8,'') 


;WITH OrderedRows AS 
( SELECT 
     Startdate,EndDate,HoursDefined,Description, ROW_NUMBER() OVER (ORDER BY Startdate,EndDate) AS RowNumber 
     FROM @tbl_WorkingHours 
) 
SELECT --before rows 
    CONVERT(datetime,'1/1/1900') AS Startdate,ISNULL(MIN(Startdate),CONVERT(datetime,'1/2/2050'))-1 AS EndDate,9.5 AS HoursDefined, CONVERT(VARCHAR (255),'') AS Description 
    FROM @tbl_WorkingHours 
UNION ALL 
SELECT --actual rows 
    Startdate,EndDate,HoursDefined,Description 
    FROM @tbl_WorkingHours 
UNION ALL 
SELECT --between rows 
    a.EndDate+1,b.Startdate-1,9.5,'' 
    FROM OrderedRows   a 
     INNER JOIN OrderedRows b ON a.RowNumber=b.RowNumber-1 
UNION ALL 
SELECT --after rows 
    ISNULL(MAX(EndDate),CONVERT(datetime,'1/1/2050')) AS Startdate,CONVERT(datetime,'1/2/2050')-1 AS EndDate,9.5 AS HoursDefined, CONVERT(VARCHAR (255),'') AS Description 
    FROM @tbl_WorkingHours 
    ORDER BY Startdate,EndDate 

OUTPUT:

Startdate    EndDate     HoursDefined   Description 
----------------------- ----------------------- ---------------------- ----------- 
1900-01-01 00:00:00.000 2010-03-03 00:00:00.000 9.5      
2010-03-04 00:00:00.000 2010-03-29 00:00:00.000 7      
2010-03-30 00:00:00.000 2010-05-03 00:00:00.000 9.5      
2010-05-04 00:00:00.000 2010-05-29 00:00:00.000 8      
2010-05-29 00:00:00.000 2050-01-01 00:00:00.000 9.5      

(5 row(s) affected)