| 
                
                    | 
                            
                                | Author | Topic |  
                                    | therealrobstoneStarting Member
 
 
                                        6 Posts | 
                                            
                                            |  Posted - 2013-10-01 : 11:08:54 
 |  
                                            | I just recently got back into working with SQL programming after a 10 year hiatus. SO I am very rusty. I have to create a table valued function that will generate a list of shifts for a given date range.Shifts at can be determined by the time of day following these rules:11PM to 7AM = 3rd shift7AM to 3PM = 1st shift3PM to 11PM = 2nd shift3rd shift technically begins the previous day. For instance, 3rd shift Monday actually starts at 11PM Sunday and continues until 7AM Monday.Parameters:@p_StartDT DATETIME@p_EndDT DATETIMEOutput columns:Column / Data type/  DescriptionStartDT / DATETIME / Start date time of shift (i.e. 2013-01-01 07:00:00.000)EndDT / DATETIME / End date  time of shift (i.e. 2013-01-01 15:00:00.000)ShiftNum / INT / Shift number (i.e. 1, 2, 3)ShiftDesc / VARCHAR(10) / String description of shift (i.e. 1st, 2nd, 3rd)The function should be inclusive. So if I pass a date range that covers several days, it should return all shifts that occurred in that date range.What I have so far, works if I pass a date range for one day. But it does not work for a date range that includes multiple days:USE [TraceSystem_DEV]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE FUNCTION [dbo].[ListShifts] (@p_StartDT DATETIME, @p_EndDT DATETIME)   RETURNS @list TABLE (StartDT DATETIME,       EndDT DATETIME, ShiftNum INT, ShiftDesc VARCHAR(10))   AS BEGIN	  IF DATEPART(HOUR, @p_StartDT) >= 7 AND DATEPART(HOUR, @p_StartDT) < 15 OR DATEPART(HOUR, @p_EndDT) > 7 AND DATEPART(HOUR, @p_EndDT) < 15		BEGIN		 INSERT INTO @list 		  (StartDT, EndDT, ShiftNum, ShiftDesc)		 VALUES		 (DATEADD(HOUR,07,CONVERT(VARCHAR(10),GETDATE(),110)), DATEADD(HOUR,15,CONVERT(VARCHAR(10),GETDATE(),110)), '1', '1st Shift')		 END		IF DATEPART(HOUR, @p_StartDT) >= 15 AND DATEPART(HOUR, @p_StartDT) < 23 OR DATEPART(HOUR, @p_EndDT) > 15 AND DATEPART(HOUR, @p_EndDT) < 23				 BEGIN					 INSERT INTO @list		  (StartDT, EndDT, ShiftNum, ShiftDesc)		  VALUES		 (DATEADD(HOUR,15,CONVERT(VARCHAR(10),GETDATE(),110)), DATEADD(HOUR,23,CONVERT(VARCHAR(10),GETDATE(),110)), '2', '2nd Shift')		 END		   		IF DATEPART(HOUR, @p_StartDT) >= 23 OR DATEPART(HOUR, @p_StartDT) < 7 OR DATEPART(HOUR, @p_EndDT) > 23 OR DATEPART(HOUR, @p_EndDT) <= 7		 BEGIN						 INSERT INTO @list		 (StartDT, EndDT, ShiftNum, ShiftDesc)		 VALUES		 (DATEADD(HOUR,23,CONVERT(VARCHAR(10),GETDATE(),110)), DATEADD(HOUR,7,CONVERT(VARCHAR(10),GETDATE(),110))+1, '3', '3rd Shift')		 END			              RETURN;   END GO---------------------------------------Thanks for taking a look.Regards,Rob Stone |  |  
                                    | James KMaster Smack Fu Yak Hacker
 
 
                                    3873 Posts | 
                                        
                                          |  Posted - 2013-10-01 : 11:26:52 
 |  
                                          | For multiple days, you will need to use a numbers table of some sort.  For testing, you can use spt_values table from master database as long as the number of days you are interested in is less than 2048. DECLARE @p_StartDT DATETIME, @p_EndDT DATETIME;SET @p_StartDT = '20130925';SET @p_EndDT = '20131002';SET @p_StartDT = CAST(@p_StartDT AS DATE); -- to remove any time portionSET @p_EndDT = CAST(@p_EndDT AS DATE);SELECT	DATEADD(dd,number,@p_StartDT) AS [Date],	DATEADD(hh,-1,DATEADD(dd,number,@p_StartDT)) [3S_Start],	DATEADD(hh,7,DATEADD(dd,number,@p_StartDT)) [3S_End],	DATEADD(hh,7,DATEADD(dd,number,@p_StartDT)) [1S_Start],	DATEADD(hh,15,DATEADD(dd,number,@p_StartDT)) [1S_End],	DATEADD(hh,15,DATEADD(dd,number,@p_StartDT)) [2S_Start],	DATEADD(hh,23,DATEADD(dd,number,@p_StartDT)) [2S_End]FROM	master.dbo.spt_values WHERE	type = 'P' AND number < DATEDIFF(dd,@p_StartDT,@p_EndDT)ORDER BY	[Date]This is not exactly in the function form that you are looking for, but easy enough to convert to a function if you do need to. |  
                                          |  |  |  
                                    | therealrobstoneStarting Member
 
 
                                    6 Posts | 
                                        
                                          |  Posted - 2013-10-01 : 13:37:35 
 |  
                                          | I took that and created this function:USE [TraceSystem_DEV]GOSET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE FUNCTION [dbo].[ListShifts] (@p_StartDT DATETIME, @p_EndDT DATETIME)   RETURNS @list TABLE (ShiftsDate DATETIME, ThirdS_Start DATETIME, ThirdS_End DATETIME, FirstS_Start DATETIME, FirstS_End DATETIME, SecondS_Start DATETIME, SecondS_End DATETIME)	  AS BEGIN		    SET @p_StartDT = CAST(@p_StartDT AS DATE); -- to remove any time portionSET @p_EndDT = CAST(@p_EndDT AS DATE);INSERT INTO @list	SELECT	DATEADD(dd,number,@p_StartDT) AS [Date], 	DATEADD(hh,-1,DATEADD(dd,number,@p_StartDT)) [ThirdS_Start],	DATEADD(hh,7,DATEADD(dd,number,@p_StartDT)) [ThirdS_End],	DATEADD(hh,7,DATEADD(dd,number,@p_StartDT)) [FirstS_Start],	DATEADD(hh,15,DATEADD(dd,number,@p_StartDT)) [FirstS_End],	DATEADD(hh,15,DATEADD(dd,number,@p_StartDT)) [SecondS_Start],	DATEADD(hh,23,DATEADD(dd,number,@p_StartDT)) [SecondS_End]  FROM	master.dbo.spt_values WHERE	type = 'P' AND number < DATEDIFF(dd,@p_StartDT,@p_EndDT)ORDER BY	[Date]	RETURN	END        GO----------------------------------------------------------Then I use this query:USE [TraceSystem_DEV]GOSELECT * FROM [dbo].[ListShifts]    ('2013-01-01 08:00:00.000', '2013-01-01 16:00:00.000')GO-------------------------------------------------But it brings up no data, just the columns.I left out the:SET @p_StartDT = '20100925';SET @p_EndDT = '20131002';From your code because it returned all shifts in those dates instead of my parameters in the query.What do I need to do to get this to work?Thanks again for the help. Regards,Rob Stone |  
                                          |  |  |  
                                    | James KMaster Smack Fu Yak Hacker
 
 
                                    3873 Posts | 
                                        
                                          |  Posted - 2013-10-01 : 13:48:36 
 |  
                                          | Change the < to <= in the where clause WHEREtype = 'P' AND number <= DATEDIFF(dd,@p_StartDT,@p_EndDT)ORDER BYAre you looking only for shifts that fall within the time part of the start and end dates as well, or for all shifts in the date range between start date and end date? |  
                                          |  |  |  
                                    | therealrobstoneStarting Member
 
 
                                    6 Posts | 
                                        
                                          |  Posted - 2013-10-01 : 14:02:01 
 |  
                                          | quote:Looking for shifts that fall within the time part of the start and end dates.Thanks again!Regards,Rob StoneOriginally posted by James K
 Change the < to <= in the where clause
 WHEREtype = 'P' AND number <= DATEDIFF(dd,@p_StartDT,@p_EndDT)ORDER BYAre you looking only for shifts that fall within the time part of the start and end dates as well, or for all shifts in the date range between start date and end date? 
 |  
                                          |  |  |  
                                    | James KMaster Smack Fu Yak Hacker
 
 
                                    3873 Posts | 
                                        
                                          |  Posted - 2013-10-01 : 14:54:47 
 |  
                                          | In that case, it might be better to have the signature that you originally proposed - with a shift number column, like shown below: SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE FUNCTION [dbo].[ListShifts]    (      @p_StartDT DATETIME ,      @p_EndDT DATETIME    )RETURNS @list TABLE    (      ShiftsDate DATETIME ,      StartDT  DATETIME ,      EndDT  DATETIME ,      ShiftNum  INT    )AS     BEGIN         INSERT  INTO @list                SELECT  DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),number) AS [Date] ,                        DATEADD(hh, -1, DATEADD(dd, number, DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),0))) [ThirdS_Start] ,                        DATEADD(hh, 7, DATEADD(dd, number,DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),0))) [ThirdS_End],                        3                FROM    master.dbo.spt_values                WHERE   type = 'P'                        AND number <= DATEDIFF(dd, @p_StartDT, @p_EndDT)                        AND @p_EndDT >= DATEADD(hh, -1, DATEADD(dd, number, DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),0)))                        AND @p_StartDT <= DATEADD(hh, 7, DATEADD(dd, number,DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),0)))				UNION ALL				                SELECT  DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),number) AS [Date] ,                        DATEADD(hh, 7, DATEADD(dd, number, DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),0))),                        DATEADD(hh, 15, DATEADD(dd, number,DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),0))),                        1                FROM    master.dbo.spt_values                WHERE   type = 'P'                        AND number <= DATEDIFF(dd, @p_StartDT, @p_EndDT)                        AND @p_EndDT >= DATEADD(hh, 7, DATEADD(dd, number, DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),0)))                        AND @p_StartDT <= DATEADD(hh, 15, DATEADD(dd, number,DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),0)))				UNION ALL                SELECT  DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),number) AS [Date] ,                        DATEADD(hh, 15, DATEADD(dd, number, DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),0))),                        DATEADD(hh, 23, DATEADD(dd, number,DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),0))),                        2                FROM    master.dbo.spt_values                WHERE   type = 'P'                        AND number <= DATEDIFF(dd, @p_StartDT, @p_EndDT)                        AND @p_EndDT >= DATEADD(hh, 15, DATEADD(dd, number, DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),0)))                        AND @p_StartDT <= DATEADD(hh, 23, DATEADD(dd, number,DATEADD(dd,DATEDIFF(dd,0,@p_StartDT),0)))             RETURN    ENDGO |  
                                          |  |  |  
                                    | therealrobstoneStarting Member
 
 
                                    6 Posts | 
                                        
                                          |  Posted - 2013-10-02 : 10:46:12 
 |  
                                          | Works perfectly. Thank you sir!Regards,Rob Stone |  
                                          |  |  |  
                                    | James KMaster Smack Fu Yak Hacker
 
 
                                    3873 Posts | 
                                        
                                          |  Posted - 2013-10-02 : 11:00:46 
 |  
                                          | You are very welcome - glad to help. |  
                                          |  |  |  
                                |  |  |  |