| 
                
                    | 
                            
                                | Author | Topic |  
                                    | sql_server_dbaPosting Yak  Master
 
 
                                        167 Posts | 
                                            
                                            |  Posted - 2014-05-22 : 13:34:47 
 |  
                                            | I am trying to write a query where i can insert addiional record when the endtime of first record is not equal to start time of next record....Below is an example..can someone please help?-- Current dataCREATE TABLE ##ItemDetail(ItemID INT, ItemCode VARCHAR(8), Startdate DATETIME, EndTime DATETIME)INSERT INTO ##ItemDetail(111, 'A', '2013-01-01', '2013-04-01')INSERT INTO ##ItemDetail(111, 'A', '2014-01-01', '2014-12-31')INSERT INTO ##ItemDetail(222, 'B', '2014-01-01', '2014-12-31')-- Below is the output...SELECT 111 AS ItemID, 'A' AS ItemCode, '2013-01-01' AS StartDate, '2013-04-01' AS EnddateUNION ALLSELECT 111 AS ItemID, 'Unknown' AS ItemCode, '2013-04-02' AS StartDate, '2013-12-31' AS EnddateUNION ALLSELECT 111 AS ItemID, 'A' AS ItemCode, '2014-01-01' AS StartDate, '2014-12-31' AS EnddateUNION ALLSELECT 222 AS ItemID, 'B' AS ItemCode, '2014-01-01' AS StartDate, '2014-12-31' AS Enddate |  |  
                                    | LampreyMaster Smack Fu Yak Hacker
 
 
                                    4614 Posts | 
                                        
                                          |  Posted - 2014-05-22 : 14:13:00 
 |  
                                          | I don't know if this will cover all the cases you might have, but it works for your sample data: WITH Cte AS(	SELECT 		*,		ROW_NUMBER() OVER (PARTITION BY ItemID ORDER BY StartDate) AS RowNum	FROM 		##ItemDetail)--  Existing RowsSELECT	ItemID	,ItemCode	,StartDate	,EndTimeFROM	CteUNION ALL-- Missing RowsSELECT 	A.ItemID	,'Unknown' AS ItemCode	,CASE WHEN A.StartDate > B.EndTime THEN DATEADD(DAY, 1, B.EndTime) ELSE A.StartDate END AS StartDate	,DATEADD(DAY, -1, A.StartDate) AS EndTimeFROM 	Cte AS AINNER JOIN	Cte AS B	ON A.ItemID = B.ItemID	AND A.RowNum = B.RowNum + 1ORDER BY	ItemID,	StartDate |  
                                          |  |  |  
                                    | TGMaster Smack Fu Yak Hacker
 
 
                                    6065 Posts | 
                                        
                                          |  Posted - 2014-05-22 : 14:35:39 
 |  
                                          | My version is almost identical.  I added some of my own samples to test.  What should happen when there is a gap of only 1 day.  my code ended upwith a start and end date of the same value. CREATE TABLE ##ItemDetail(ItemID INT, ItemCode VARCHAR(8), Startdate DATETIME, EndTime DATETIME)INSERT INTO ##ItemDetail values (111, 'A', '2013-01-01', '2013-04-01')INSERT INTO ##ItemDetail values (111, 'A', '2014-01-01', '2014-12-31')INSERT INTO ##ItemDetail values (222, 'B', '2014-01-01', '2014-12-31')INSERT INTO ##ItemDetail values (333, 'c', '2014-01-01', '2014-02-15')INSERT INTO ##ItemDetail values (333, 'c', '2014-02-16', '2014-03-03')INSERT INTO ##ItemDetail values (333, 'c', '2014-03-04', '2014-05-01')INSERT INTO ##ItemDetail values (333, 'c', '2014-05-04', '2014-05-20')INSERT INTO ##ItemDetail values (333, 'c', '2014-05-21', '2014-05-30')INSERT INTO ##ItemDetail values (333, 'c', '2014-05-31', '2014-06-05')INSERT INTO ##ItemDetail values (333, 'c', '2014-06-07', '2014-06-30');with id (ItemID, ItemCode, Startdate, EndTime, rid)as(       select ItemID              , ItemCode              , Startdate              , EndTime              , row_number() over (partition by itemid order by startdate)       from   ##itemdetail)insert ##itemDetailselect a.itemid       ,'Unknown' as ItemCode       ,dateadd(day, 1, a.endTime) as startDate       ,dateadd(day, -1, b.startDate) as endTimefrom   id aleft outer join id b        on b.itemid = a.itemid        and b.rid-1 = a.ridwhere  datediff(day, a.endtime, b.startdate) > 1select * from ##itemDetail order by itemID, startDateOUTPUT:ItemID      ItemCode Startdate               EndTime----------- -------- ----------------------- -----------------------111         A        2013-01-01 00:00:00.000 2013-04-01 00:00:00.000111         Unknown  2013-04-02 00:00:00.000 2013-12-31 00:00:00.000111         A        2014-01-01 00:00:00.000 2014-12-31 00:00:00.000222         B        2014-01-01 00:00:00.000 2014-12-31 00:00:00.000333         c        2014-01-01 00:00:00.000 2014-02-15 00:00:00.000333         c        2014-02-16 00:00:00.000 2014-03-03 00:00:00.000333         c        2014-03-04 00:00:00.000 2014-05-01 00:00:00.000333         Unknown  2014-05-02 00:00:00.000 2014-05-03 00:00:00.000333         c        2014-05-04 00:00:00.000 2014-05-20 00:00:00.000333         c        2014-05-21 00:00:00.000 2014-05-30 00:00:00.000333         c        2014-05-31 00:00:00.000 2014-06-05 00:00:00.000333         Unknown  2014-06-06 00:00:00.000 2014-06-06 00:00:00.000333         c        2014-06-07 00:00:00.000 2014-06-30 00:00:00.000EDIT:after looking at Lamprey's version I realize my LEFT OUTER JOIN is essentially an INNER join as I refer to both tables in the WHERE clause - so that should change to INNER.  We even named our table aliases the same - great minds think alike?  Be One with the OptimizerTG |  
                                          |  |  |  
                                    | LampreyMaster Smack Fu Yak Hacker
 
 
                                    4614 Posts | 
                                        
                                          |  Posted - 2014-05-22 : 15:29:25 
 |  
                                          | quote:NICE! :)Yeah, the sample data was pretty limited. I'd assume my version would need a similar WHERE clause to your version.Originally posted by TG
 EDIT:after looking at Lamprey's version I realize my LEFT OUTER JOIN is essentially an INNER join as I refer to both tables in the WHERE clause - so that should change to INNER.  We even named our table aliases the same - great minds think alike?
  Be One with the OptimizerTG 
 |  
                                          |  |  |  
                                    | sql_server_dbaPosting Yak  Master
 
 
                                    167 Posts | 
                                        
                                          |  Posted - 2014-05-22 : 19:58:06 
 |  
                                          | Good catch about the one day gap. Thanks Lampery and TG. This works like a charm. But here is an another case where i am not sure what to do.....If the EndTime of the last record is less than today, then i wanted to add another record with the StartDate as EndTime of last record + 1...below is an example...CREATE TABLE ##ItemDetail(ItemID INT, ItemCode VARCHAR(8), Startdate DATETIME, EndTime DATETIME)INSERT INTO ##ItemDetail values (111, 'A', '2013-01-01', '2013-04-01')INSERT INTO ##ItemDetail values (111, 'A', '2014-01-01', '2014-04-30')INSERT INTO ##ItemDetail values (222, 'B', '2014-01-01', '2014-12-31')INSERT INTO ##ItemDetail values (333, 'c', '2014-01-01', '2014-02-15')INSERT INTO ##ItemDetail values (333, 'c', '2014-02-16', '2014-03-03')INSERT INTO ##ItemDetail values (333, 'c', '2014-03-04', '2014-05-01')INSERT INTO ##ItemDetail values (333, 'c', '2014-05-04', '2014-05-20')INSERT INTO ##ItemDetail values (333, 'c', '2014-05-21', '2014-05-30')INSERT INTO ##ItemDetail values (333, 'c', '2014-05-31', '2014-06-05')INSERT INTO ##ItemDetail values (333, 'c', '2014-06-07', '2014-06-30')INSERT INTO ##ItemDetail values (444, 'D', '2013-01-01', '2013-05-31')-- The output like earlier messages andUNION ALLSELECT 111, 'Unknown', '2014-05-01 00:00:00.000', '2099-12-31 00:00:00.000'UNION ALLSELECT 444, 'Unknown', '2014-06-01 00:00:00.000', '2099-12-31 00:00:00.000'ORDER BY ItemID, Startdate |  
                                          |  |  |  
                                    | LampreyMaster Smack Fu Yak Hacker
 
 
                                    4614 Posts | 
                                        
                                          |  Posted - 2014-05-23 : 13:24:46 
 |  
                                          | Something like this: WITH Cte AS(	SELECT 		*,		ROW_NUMBER() OVER (PARTITION BY ItemID ORDER BY StartDate) AS RowNum	FROM 		##ItemDetail)--  Existing RowsSELECT	ItemID	,ItemCode	,StartDate	,EndTimeFROM	CteUNION ALL-- Missing RowsSELECT 	A.ItemID	,'Unknown' AS ItemCode	,CASE 		WHEN A.StartDate > B.EndTime THEN DATEADD(DAY, 1, B.EndTime) 		WHEN B.EndTime IS NULL THEN DATEADD(DAY, 1, A.EndTime) 		ELSE A.StartDate 	END AS StartDate	,CASE 		WHEN B.EndTime IS NULL THEN CAST('99991231' AS DATETIME)		ELSE DATEADD(DAY, -1, A.StartDate) 	END AS EndTimeFROM 	Cte AS ALEFT OUTER JOIN	Cte AS B	ON A.ItemID = B.ItemID	AND A.RowNum + 1 = B.RowNumWHERE	DATEDIFF(DAY, A.EndTime, B.StartDate) > 1	OR	(		A.EndTime < GETDATE()		AND B.ItemID IS NULL	)ORDER BY	ItemID,	StartDate |  
                                          |  |  |  
                                |  |  |  |