on 2019 Feb 16 6:42 PM
I need help with a SQL... I have a field with an available capacity per day for hours in table tblCapacity. With this field, I want to calculate the available capacity per week for hours. I will exclude weekends and the dates that are in my table tblExcludeDates. The current week is submitted as a where condition.
CREATE TABLE tblCapacity ( WorkCenter VARCHAR(12), Capacity Numeric(16,2) ); INSERT tblCapacity VALUES ('WC1', 7.5 ); INSERT tblCapacity VALUES ('WC2', 8 ); COMMIT; CREATE TABLE tblExcludeDates ( ExceptionDate DATE, Type INTEGER ); INSERT tblExcludeDates VALUES ('2019-03-27', 1); INSERT tblExcludeDates VALUES ('2019-04-24', 1); INSERT tblExcludeDates VALUES ('2019-04-25', 1); INSERT tblExcludeDates VALUES ('2019-05-01', 1); INSERT tblExcludeDates VALUES ('2019-12-24', 1); INSERT tblExcludeDates VALUES ('2019-12-25', 1); COMMIT;
As an example, with my sql, I want to type type like this:
SELECT WeekCapacity FROM ... WHERE WorkCenter = 'WC1' AND YearWeek = '1917'
WeekCapacity for week 17 in work center WC1 will then be 22.5 hours. If I specify week 19 in the condition, WeekCapacity will be 37,5 hours in work center WC1.
Here's a starting point that lists the number of work days in the specified week.
begin declare strYearWeek varchar(4) = '1917'; declare nYear int; declare nWeek int; declare dtNewYear date; set nYear = 2000 + cast(left(strYearWeek, 2) as int); set nWeek = cast(substr(strYearWeek, 3) as int); set dtNewYear = ymd(nYear, 1, 1); select count(*) as NumberOfWeekdays from (select cast(dateadd(day, numberOfDays.row_num, dtNewYear) as date) as dtDayOfYear from sa_rowgenerator(0, datediff(day, dtNewYear, ymd(nYear + 1, 1, 1)) - 1) numberOfDays where datepart(weekday, dtDayOfYear) between 2 and 6 and datepart(calweekofyear, dtDayOfYear) = nWeek except select ExceptionDate from tblExcludeDates) DT end;
returns 3 for '1917' and 5 for '1919'.
Some hints:
I'm using a "brute force" approach to list all days in the specified year and then check whether they fall into the according week.
"datediff(day, dtNewYear, ymd(nYear + 1, 1, 1))" counts the number of days between the specified year's first day and that of the new year, thereby calculating this year's number of days, so 365 for 2019.
"sa_rowgenerator(... -1) numberOfDays" then generates a row with a number for each day, starting with 0, so for 2019 up to 364.
"select cast(dateadd(day, numberOfDays.row_num, dtNewYear) as date) as dtDayOfYear from ... numberOfDays" then lists all days in the according year.
The WHERE clause checks via "datepart(weekday, dtDayOfYear) between 2 and 6" whether they are "working days" (assuming those are Monday -Friday, note that Sunday = 1)
and checks via "datepart(calweekofyear, dtDayOfYear) = nWeek" whether they belong to the specified week. (Note, there are different definitions of when the first week of a year starts for different countries, so that may have to be adapted!) - So that query will usually return 5 days unless the week partly falls into another year.
The EXCEPT is added to exclude those days from your table.
The whole query is then used as a derived table and its result set is simply counted.
So finally you would just calculate the resulting "NumberOfWeekdays" with the capacity per Work Center.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you very much! This is exactly the functionality I was looking for. Thanks also for your exhaustive description of the functionality.
One thing I missed is that the dates available tblException are not always full days. There is an additional column in the table that I missed (ExceptionDay) that tells how much of the day is the exception. 1 is full day, 0.5 is half day, 0.25 is 2h etc. Full day is always 8 hour. I also need to include this column in the calculation. Do you have any good suggestions on how to do it too?
The table looks like this:
CREATE TABLE tblExcludeDates ( ExceptionDate DATE, Type INTEGER, ExceptionDay INTEGER ); INSERT tblExcludeDates VALUES ('2019-03-27', 1, 1); INSERT tblExcludeDates VALUES ('2019-04-24', 1, 1); INSERT tblExcludeDates VALUES ('2019-04-25', 1, 0.5); INSERT tblExcludeDates VALUES ('2019-05-01', 1, 0.25); INSERT tblExcludeDates VALUES ('2019-12-24', 1, 1); INSERT tblExcludeDates VALUES ('2019-12-25', 1, 0.75);
How does the "half day" relate to the different working hours per day in the different "Work Centers"? For WC1, you say the working day is 7.5 hours long, how long is it for "half days" and the like?
In other words: Are these "ExpectionDay" values
Besides that, that additional requirement makes the query way more complicated. I guess you would need a two-step approach:
User | Count |
---|---|
79 | |
10 | |
10 | |
10 | |
10 | |
9 | |
8 | |
7 | |
5 | |
5 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.