on 07-16-2014 8:32 PM
I need to calculate number of Business Days in BODS. Lets say I have One source table and One Date Dimension table to identify Business Day and need to calculate the no of working days and load in to FACT table (Like in screenshot below)?
By adding Query transform, I can calculate no of Days, but how to calculate working days between ORDER_RECEIVED_DATE and ORDER_SHIPPED_DATE.
SQL: select count(*) from DIM_DATE where DATE between ORDER_RECEIVED_DATE and ORDER_SHIPPED_DATE and HOLIDAY_FLAG='NO'
Add an extra column to DIM_DATE, WORKING_DAY_NO, to contain an ever increasing sequence number that counts the number of working days since the beginning of your calendar. WORKING_DAY_NO can be easily populated with a call to a function f_working_days(HOLIDAY_FLAG) in its mapping:
if ($HOLIDAY_FLAG='NO')
begin
$G_working_day = $G_working_day + 1;
end
return ($G_working_day);
$G_working_day is a global variable, initialised to 0.
Calculating the number of business days between ORDER_RECEIVED_DATE and ORDER_SHIPPED_DATE has become a piece of cake, now:
lookup(DIM_DATE, WORKING_DAY_NO, 0, 'PRE_LOAD_CACHE', DATE , ORDER_RECEIVED_DATE) - lookup(DIM_DATE, WORKING_DAY_NO, 0, 'PRE_LOAD_CACHE', DATE , ORDER_SHIPPED_DATE)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Prashanth Chinta,
You can use below function to calculate the no. of days:
date_diff(ORDER_RECEIVED_DATE, ORDER_SHIPPED_DATE,'D')
Now you need to subtract the no. of holidays which comes between these two dates then you are done. And to calculate the no. of holidays you need to have all the dates between these two dates which can be joined with DIM_DATE table to count the days for holidays.
Hope this helps.
Regards,
Ansari MS
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Ansari,
If I understand correct, Dataflow looks something like below, after Qry_Lkp, I have 30 columns including,
ORDER_SHIPPED_DATE, ORDER_RECEIVED_DATE, NO_OF_DAYS. Now I joined DIM_DATE on DIM_DATE.DATE between ORDER_RECEIVED_DATE and ORDER_SHIPPED_DATE on Qry_GrpBy. Here is my question, now if i do add one more column to calculate Holidays in Qry_GrpBy, lets say NO_OF_HOLIDAYS: what should be the formula? so I can add one more Query transform and do NO_OF_DAYS - NO_OF_HOLIDAYS to get Business Days.
If you say something like count(), then I need to add remaining 29 columns in Group by clause right?
Is there any alternate way....
I have simulated this Job in my repository and and below are the steps by step implementation.
Your Dataflow will look like below. It contains the source and Target table with expected results. Hope this is what you are looking for.
DIM_DATE table contains all the dates in a year and mark each date either Holiday as 'YES' or 'NO'
Qry_Total_Ship_Days Query Transform
Qry_Join Query Transform
Qry_Filter_Holidays Query Transform
Qry_Cnt_Holidays Query Transform
Qry_Cnt_Holidays Query Transform (This is to show the groupby columns)
Qry_Cal_Ship_Days Query Transform
Thanks for your time, I did similar like yours, except to overcome Group by on 29 columns and duplicate Dates, I added 2 extra Qry Transforms like in screenshot and calculated Holidays separately. My fact table grain is Product, due to duplicate dates, count(*) might give wrong results. But I got the idea from yours and thanks for bonus tip (Date_Diff() + 1).
Loaded data successfully, created Universe, users happily testing in BI.
To get working days, you may have to use a SQL Query like show in the link with case statement - sql server 2005 - Business Days calculation - Stack Overflow
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You don't need to do a SQL transfer, write a stored procedure and call it as a function in the Query transform.
Some thing like this from google -
CREATE FUNCTION "fnGetBusinessDays"
(
@startdate datetime,
@enddate datetime
)
RETURNS integer
AS
BEGIN
DECLARE @days integer
SELECT @days =
DATEDIFF(d,@startdate,@enddate)
- DATEDIFF(wk,@startdate,@enddate) * 2
- CASE
WHEN DATENAME(dw, @startdate) <> 'Saturday' AND DATENAME(dw, @enddate) = 'Saturday' THEN 1
WHEN DATENAME(dw, @startdate) = 'Saturday' AND DATENAME(dw, @enddate) <> 'Saturday' THEN -1
ELSE 0
END
- (SELECT COUNT(*) FROM holidays WHERE bankholiday BETWEEN @startdate AND @enddate AND DATENAME(dw, bankholiday) <> 'Saturday' AND DATENAME(dw, bankholiday) <> 'Sunday')
RETURN (@days)
END
GO
User | Count |
---|---|
80 | |
9 | |
9 | |
7 | |
7 | |
7 | |
6 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.