Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
Bex
Aged Yak Warrior
580 Posts |
Posted - 2005-10-13 : 07:18:43
|
Hello allRight, I have an issue, and I am trying to work it out, but cannot see the woods for the trees. Therefore, I am hoping that some new eyes can shed some light on the problem:The RequirementCount the number of incoming mail that completed a process within a specified time for SLA purposes (an example would be when a mail batch was scanned and indexed) I have a start_time and an end_time of when each process has completedI have to calculate the working hours (down to the nearest millisecond) it took to complete the process from start to finishThe working hours differ per process So farI have a table containing the working hours for each process (as example of data is below):StartTime EndTime Process ----------------------- ------------------------ -----------------------1900-01-01 09:00:00.000 1900-01-01 17:00:00.000 Email and Faxing1900-01-01 07:30:00.000 1900-01-01 17:00:00.000 Scanning and Indexing I created a function to caclulate the number of working hours per day (returning a date)ALTER FUNCTION fn_LengthOfWorkingDay(@process VARCHAR(25))RETURNS DATETIMEASBEGIN DECLARE @returnDate DATETIME SELECT @returnDate = EndTime - StartTime FROM WorkingDayHours WHERE Process = @process RETURN @returnDateEND For scanning and indexing it returns:1900-01-01 09:30:00.000 My problem is that I need to calculate the number of working hours that have occurred between the start_time and the end_time of a process. I wrote a function to return the difference (one in milliseconds and another in a datetime format):Returns a dateCREATE FUNCTION fn_CalculateDateDifference( @startDate DATETIME, @endDate DATETIME)RETURNS DATETIMEASBEGIN DECLARE @returnDate DATETIME SELECT @returnDate = @endDate - @startDate RETURN @returnDateEND Returns number of milliseconds:CREATE FUNCTION fn_CalculateMSBetweenDates( @startDate DATETIME, @endDate DATETIME)RETURNS INTASBEGIN DECLARE @milliseconds INT SELECT @milliseconds = (SELECT DATEDIFF(MS,@startDate, @endDate)) RETURN @millisecondsEND However, neither of these account for weekends or the fact that these are total times and not 'working hours'. How can I calulate the number of working hours that have occured between the start and end times of the process, taking into account weekends????Some sample data of start and end times for scanning and indexing are below:rls_end_time Scan Start time Time Difference ------------------------ ------------------------- ------------------------2005-09-08 09:50:50.000 2005-09-08 09:44:51.000 1900-01-01 00:05:59.0002005-09-13 15:38:59.000 2005-09-09 09:52:53.000 1900-01-05 05:46:06.0002005-09-09 11:13:29.000 2005-09-09 10:51:13.000 1900-01-01 00:22:16.0002005-09-14 10:53:44.000 2005-09-13 07:58:02.000 1900-01-02 02:55:42.000 So although I know the difference in time between the two dates, can i write a function that calculates the total amount of that time is actually 'working hours'. Would it be best to calculate in date format or determine or milliseconds?God, I know this sounds so muddled, and the answer may be super simple, but my brain is all mixed up so pleeeeeeease, someone offer me some clarity or a new way of thinking!Thanks in advanceHearty head pats |
|
|
Bex
Aged Yak Warrior
580 Posts |
Posted - 2005-10-13 : 07:53:30
|
| Ok, I have thought of something and would appreciate an opinion. Apologies if this is unclear a I am having a brainstorm:· First of all, calculate the number of full days that have passed between the two dates· (I do not know a function that can count a the number of days that have lapsed between a date range)· Calculate the working hours for a specific process by querying the process table and times by the number of full days that have lapsed. · For example, to work out the number of milliseconds that have passed for 2 full days for Scanning and Indexing, then (SELECT (DATEDIFF (ms, <workday_starttime>, < workday_endtime>) X 2) FROM WorkingDayHours WHERE Process = ‘Scanning and Indexing’· Calculate the time lapsed between the start_time and the end of the working day. For example, (DATEDIFF(ms, < process_start_time >,< workday_endtime >))· Do the same to work out the time passed during the last day (DATEDIFF(ms, < workday_starttime >,< process_end_time >))· Add all the results together to obtain the complete working time that has lapsed.· If any of the full days fall on a weekend, then do not include them in the total.Right, now, although I have worked out some logic (whether it is correct I don’t know), but I have no idea how to implement it – For example, Is there a function to return the count of days that occur between a date range??Anyway, your opinions are greatly appreciated!Hearty head pats |
 |
|
|
Bex
Aged Yak Warrior
580 Posts |
Posted - 2005-10-13 : 08:04:59
|
| Apologies for being a spaz, of course I know a function to count number of days between a date range - flipping DATEDIFF - oh my god, I hve been working on this for too long! However, I still want advice!Hearty head pats |
 |
|
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2005-10-13 : 09:04:47
|
| >>Is there a function to return the count of days that occur between a date range??Is this?Select DateDiff(day,Date1,Date2) from yourTableMadhivananFailing to plan is Planning to fail |
 |
|
|
Bex
Aged Yak Warrior
580 Posts |
Posted - 2005-10-13 : 10:02:04
|
| Yeah, I know (see the email above yours)! Told you I was muddled! Doh!Hearty head pats |
 |
|
|
Bex
Aged Yak Warrior
580 Posts |
Posted - 2005-10-13 : 13:08:07
|
For anyone who is interested, here is the solution (after much brain ache):CREATE FUNCTION fn_CalculateWorkingHours( @startDate DATETIME, @endDate DATETIME, @process VARCHAR(25))RETURNS BIGINTASBEGIN DECLARE @milliseconds BIGINT DECLARE @numOfFullDays TINYINT DECLARE @timePortion DATETIME SET @numOfFullDays = 0 IF (DATEDIFF(DAY,@startDate,@endDate) > 0) BEGIN --Calculate the time lapsed between the start of the process to the end of the working day SELECT @timePortion = @startDate - CAST(FLOOR(CAST(@startDate AS FLOAT))AS SMALLDATETIME) SELECT @milliseconds = DATEDIFF(ms,@timePortion, WorkingDayHours.EndTime) FROM WorkingDayHours --Calculate the time lapsed between the start of the working day and the end of the process SELECT @timePortion = @endDate - CAST(FLOOR(CAST(@endDate AS FLOAT))AS SMALLDATETIME) SELECT @milliseconds = @milliseconds + DATEDIFF(ms, WorkingDayHours.StartTime, @timePortion) FROM WorkingDayHours WHERE Process = @process --Add a day onto the start date as you do not want to include the first day in the full working day count SELECT @startDate = DATEADD(DAY,1,@startDate) --Eradicate the time portion of the dates SELECT @startDate = CAST(FLOOR(CAST(@startDate AS FLOAT))AS SMALLDATETIME) SELECT @endDate = CAST(FLOOR(CAST(@endDate AS FLOAT))AS SMALLDATETIME) --Calculate the number of full working days that have lapsed between the start and end date of the process --As long as the day is less then (not <=) the last day date will not be included in the full working day count WHILE @startDate < @endDate BEGIN --If the date is not included in the dates held in the BankHoliday Table, then it can be included in the count IF NOT EXISTS(SELECT BankHolidayDate FROM BankHoliday WHERE BankHolidayDate = @startDate) BEGIN --If the day falls on a weekend, then it is not included in the count SELECT @numOfFullDays = @numOfFullDays + (CASE DATENAME(DAY,@startDate) WHEN 'Saturday' THEN 0 WHEN 'Sunday' THEN 0 ELSE 1 END) END SELECT @startDate = DATEADD(DAY, 1, @startDate) END --Add the number of milliseconds for the working days to the total SELECT @milliseconds = @milliseconds + (@numOfFullDays * dbo.fn_CalculateMSBetweenDates(StartTime, EndTime)) FROM WorkingDayHours WHERE Process = @process ENDELSE BEGIN SELECT @milliseconds = DATEDIFF(MS,@startDate,@endDate) END RETURN (@milliseconds)END Hearty head pats |
 |
|
|
|
|
|
|
|