Calculated Column DAX Formula for Date Is Less Than Last Friday - ssas

I need to add a calculated column that returns 'Yes' if the row's date (datekey on this date table) is on or before last Friday, 'No' otherwise.
To start, I've got IF(DimDate[DateKey] < DATEVALUE("2017-10-27"), "Yes", "No") however, I obviously need the 2017-10-27 date to be dynamic.
Is there an application of the DATEDIFF function that will return the date of the last Friday?

You can make use of the WEEKDAY function to do the calculation.
By working out the days to subtract in order to get the date of last Friday: (1 = Monday, 7 = Sunday)
WEEKDAY | OFFSET
-------------------
1 | -3
2 | -4
3 | -5
4 | -6
5 | -7
6 | -1
7 | -2
The following DAX measure can calculate last Friday:
Last Friday =
VAR WeekdayOfToday = WEEKDAY(TODAY(), 2)
RETURN
IF(
WeekdayOfToday >= 6,
TODAY() - (WeekdayOfToday - 5),
TODAY() - (WeekdayOfToday + 2)
)
Then you can use it for your calculated column:
On or before Last Friday = IF(DimDate[DateKey] <= [Last Friday], "Yes", "No")
(On or before should be <= by the way)
Results:

Related

SQL add Order column that represents Day of the week

Working a 3 month dataset that has a record/line for each day in that time frame. I want to add a "Order" column that possesses values of 0-6 or 1-7. Where, for example, if query executed on Monday - Mondays would be 0, Tuesdays: 1, Wednesdays: 2, Thursdays: 3, Fridays:4, Saturdays: 5, Sundays: 6. If the query was executed on a Friday then Friday records would contain: 0, Saturday: 1, Sunday: 2, etc...
Ultimate goal is to use this query in a PBI dashboard - where, after aggregating by day of week - the current day is shown first when sorted by the order column; i.e. I don't want the results always showing Sunday through Saturday. If it is Wednesday and someone is looking at the dashboard, I'll want the order of data to be W, Th, F, S, Su, M, T. I believe this can be accomplished with this order column.
Any ideas? Thank you!
You want the day of the week based on the current day. This is really an arithmetic calculation, where you want the difference between the particular date and the current date mod 7, but with a bit more arithmetic.
This does the calculation:
select 6 - mod(trunc(sysdate - 1) - <datecol>, 7)
To compute a relative "day" you can do:
mod(to_char(t.recorded, 'D') + 7 - to_char(current_date, 'D'), 7)
For example:
select
t.*,
mod(to_char(t.recorded, 'D') + 7 - to_char(current_date, 'D'), 7) as diff
from t;
Result (today is Monday):
RECORDED VALUE DIFF
---------- ------ ----
2021-01-01 123 4
2021-01-02 456 5
2021-01-03 789 6
2021-01-04 12 0
2021-01-05 345 1
2021-01-06 678 2
2021-01-07 901 3
2021-01-08 234 4
2021-01-09 567 5
See running example at SQL Fiddle.

How to calculate the number of days of first week of the month in SAS.if we consider Saturday as first week day

I am using intnx function.
date1=intnx('qtr',"01APR2021"d,0,'b');
I am thinking of following algo-
1.Check if last month's last day is not Friday.
2.Calculate the number of days till Friday appears(Current Month).
Can anyone help me with this?
Use INTNX to compute the 1st of the month, and then WEEKDAY of that to compute the number of days in the first week.
WEEKDAY function results are
1st-want 1st_want-v2
1 Sunday 1 2
2 Monday 2 3
3 Tuesday 3 4
4 Wednesday 4 5
5 Thursday 5 6
6 Friday 6 7
7 Saturday 7 1
Depending on what you want, (suppose the 1st is a Saturday, do you want 1 or 7 for your result?) For 1, you will need to perform additional calculations.
Example:
Presume if first is a Saturday you want 7 days in first week result.
data have;
call streaminit (2021);
do _n_ = 0 to 23;
date = intnx('month', '01-jan-2019'd, _n_) + rand('integer', 27);
output;
end;
format date date11.;
run;
data want;
set have;
month_1st = intnx('month', date, 0);
sas_weekday_1st = weekday(month_1st);
result = sas_weekday_1st;
result_v2 = mod(sas_weekday_1st,7) + 1;
format month_1st date11.;
run;
Find the first of the month (INTNX() or MDY())
Find the first friday (day=6) of the month (NWKDOM())
Subtract
Assume month and year are provided.
data want;
year = 2020;
month = 1;
start_date = mdy(month, 1, year);
first_friday = nwkdwom(1, 6, month, year);
length_week = start_date - first_friday + 1;
*Toms correction:;
length_week2 = day(nwkdom(1,6,month(date),year(date));
run;
Sounds like you want to know the date of the first Friday in the month. And hence the day of the month of the first Friday in the month.
So let's start with a dataset that has a month that starts on each day of the week.
data example;
input date :date9.;
format date date9.;
dow = weekday(date);
downame=put(date,downame.-l);
cards;
01OCT2000
01MAY2000
01FEB2000
01MAR2000
01JUN2000
01SEP2000
01JAN2000
;
Now we can use the INTNX() function with the WEEK interval to find the date of the first Friday. We could then use the DAY() function to find the day of the month for that Friday and hence how many days are in the first week of the month.
To get the first Friday find the Saturday at the end of the week containing the second day of the month and subtract one to move back to Friday.
data want;
set example;
friday = intnx('week',date+1,0,'e')-1 ;
want = day(friday);
want_name=put(friday,downame.-l);
format friday date9.;
run;
Results:
Obs date dow downame friday want want_name
1 01OCT2000 1 Sunday 06OCT2000 6 Friday
2 01MAY2000 2 Monday 05MAY2000 5 Friday
3 01FEB2000 3 Tuesday 04FEB2000 4 Friday
4 01MAR2000 4 Wednesday 03MAR2000 3 Friday
5 01JUN2000 5 Thursday 02JUN2000 2 Friday
6 01SEP2000 6 Friday 01SEP2000 1 Friday
7 01JAN2000 7 Saturday 07JAN2000 7 Friday
To do it with any day in the month use the INTNX() function with MONTH interval to find the first day of the month (and add one to find the second day of the month).
length_week1=day(intnx('week',intnx('month',date,0,'b')+1,0,'e')-1);

Teradata SQL Week Number - Week 1 starting 1st Jan with weeks aligned to specific day of the week

my first post on here so please be gentle...
I'm trying to create a week number variable in Teradata (SQL) that does the following:
Week 1 always starts on 1st January of the given year
Week numbers increment on the specified day of the week
For example: If Saturday was the specified day of the week:
2019-01-01 would be the start of week 1, 2019, changing to week 2 on 2019-01-05
2020-01-01 would be the start of week 1, 2020, changing to week 2 on 2020-01-04
I have come up wit the following based on an Excel function however it doesn't quite work as expected:
ROUND(((DATE_SPECIFIED - CAST(EXTRACT(YEAR FROM DATE_SPECIFIED) || '-01-01' AS DATE) + 1) - ((DATE_SPECIFIED - DATE '0001-01-06') MOD 7 + 1) + 10) / 7) AS REQUIRED_WEEK
The last digit of the section - DATE '0001-01-06' deals with the specified day of the week, where '0001-01-01' would be Monday.
This works in some cases however for some years, the first week number is showing as 0 where it should be 1, e.g. 1st Jan 2018 / 2019 are fine whereas 1st Jan 2020 is not.
Any ideas to correct this would be gratefully received.
Many thanks,
Mike
You can apply NEXT_DAY for both the specified date and Jan 1st of that year, e.g. for Saturday as week start:
(Next_Day(DATE_SPECIFIED,'SAT') - Next_Day(Trunc(DATE_SPECIFIED,'yyyy'),'SAT')) / 7 +1
Hmmm . . . I'm a bit week on Teradata functions. But the idea is to get the start of the second week. This follows the rule:
Jan 1 weekday (TD) 2nd week
Sunday 1 01-02
Monday 2 01-08
Tuesday 3 01-07
Wednesday 4 01-06
Thursday 5 01-05
Friday 6 01-04
Saturday 7 01-03
I think the following logic calculates this:
select t.*,
(case when td_day_of_week(cast(extract(year from DATE_SPECIFIED) || '-01-01' as date) ) = 1
then cast(extract(year from DATE_SPECIFIED) + '-01-02' as date)
else extract(year from DATE_SPECIFIED) + 10 - cast(td_day_of_week(cast(extract(year from DATE_SPECIFIED) || '-01-01') as date)
from t;
Then do you your week calculate either from the second week or subtract one more week to get when the first week really starts.

Extract weekend days from date

I have date field and from that date field i am trying to extract only weekends i.e. in my case Saturday and Sunday is weekend.
So how can i extract weekends from date?
If below dates are in weekend then should be like this:
Date day working hours
01/01/2019
02/01/2019
03/01/2019
04/01/2019
05/01/2019 weekend 24
06/01/2019 weekend 87
07/01/2019
08/01/2019
09/01/2019
10/01/2019
Data link: https://www.dropbox.com/s/xaps82qyyo6i0fa/ar.xlsx?dl=0
You can use WeekDay functon. This function accepts date value/field and return the day of the week. The returned value is in dual format - day name and day number.
So you can create additional field that checks if the day number is >= 5 (day numbers are starting from 0 so Saturday = 5 and Sunday = 6)
RawData:
LOAD
AttendanceDay,
if(WeekDay(AttendanceDay) >= 5, 1, 0) as isWeekend,
Employee_ID,
WorkingHours
FROM
[..\Downloads\ar.xlsx]
(ooxml, embedded labels, table is Attendances_20191119_0838)
;
Resulted table after the reload:

Excel: No. of Weekdays in a given week

My Data
A B C
1 Created Date Week No. of WorkDays
2 6/20/2018 11:36 06-w4 5
3 6/26/2018 12:56 06-w5 5
4 7/6/2018 23:01 07-w1 5
5 6/18/2018 18:11 06-w4 5
6 6/15/2018 12:01 06-w3 5
7 6/1/2018 13:31 06-w1 1
8 6/8/2018 12:17 06-w2 5
9 6/1/2018 13:32 06-w1 1
10 7/30/2018 13:32 07-w5 2
I have a week function that says whether an issue was created in Week 1 or 2 or so on. But for my calculation I need to consider workdays in that week, how do I do it. I'm calculating the no. of weekdays in that week manually now.
For example: June Week 1: No. of Weekdays is 1, because June 1 is Friday and June 2 is Saturday. Similarly for July Week 5 it is 2 days because July 29 is Sunday, July 30 & 31 are the weekdays.
My current formula for Week is
=CONCATENATE(TEXT(A1,"MM"),"-w",WEEKNUM(A1,1)-WEEKNUM(DATE(YEAR(A1),MONTH(A1),1),1)+1)
I'm trying out to use Workday function, but it does not provide my desired result.
Kindly help me out with this.
If the date in the A column is always a weekday, you can use this:
If that date can also be a weekend day, it will take the working days of the previous week. If you want to take the workinf days of the next week, you have to fiddle around still a bit.
=MIN(5,IF(MONTH(A2-WEEKDAY(A2,3))<MONTH(A2),7-WEEKDAY(DATE(YEAR(A2),MONTH(A2),1),1),IF(MONTH(A2+5-WEEKDAY(A2,2))>MONTH(A2),WEEKDAY(DATE(YEAR(A2),MONTH(A2)+1,0),2),5)))
First MIN: restrict to max 5 working days
First IF(): check if monday before or on date in A2 is in previous month
If so: take 7 minus weekday of first of month (sunday being 1)
If not so: second IF: check if friday this week is in next month
If so: take the weekday of the last of this month (monday being 1)
If not so: week in the middle of month, return 5
This of course does not take into account public holidays, only weekends.
For an inclusive # or workdays (e.g. Friday is 1 workday) try,
=NETWORKDAYS.INTL(A2, A2+5-WEEKDAY(A2,2), 1)
NETWORKDAYS.INTL allows for an optional holiday list if you want to create one.
Wrote my own VBA Formula - Results are as below
A B C D
1 Created Date Week No. of WorkDays No. of Days - Formula
2 6/20/2018 11:36 06-w4 5 5
3 3/2/2018 12:56 03-w1 2 2
4 7/6/2018 23:01 07-w1 5 5
5 6/18/2018 18:11 06-w4 5 5
6 6/15/2018 12:01 06-w3 5 5
7 6/1/2018 13:31 06-w1 1 1
8 6/8/2018 12:17 06-w2 5 5
9 6/1/2018 13:32 06-w1 1 1
10 7/30/2018 13:32 07-w5 2 2
Formula
=CalculateWorkdaysInWeek(A2)
VBA Code
Function CalculateWorkdaysInWeek(WeekRange As Range) As Variant
'Assume Week 2, 3 & 4 will always have 5 days
Dim WeekNo As Double
'Check if Week is 1 or 5
WeekNo = (Application.WorksheetFunction.WeekNum(WeekRange, 1) - _
Application.WorksheetFunction.WeekNum(DateSerial(Year(WeekRange), Month(WeekRange), 1))) + 1
Dim NoOfWeekDays As Integer
If WeekNo = 1 Then
FirstWeekDay = 7 - Weekday(DateSerial(Year(WeekRange), Month(WeekRange), 1), vbSunday)
If FirstWeekDay > 5 Then
FirstWeekDay = 5
End If
NoOfWeekDays = FirstWeekDay
ElseIf WeekNo = 5 Then
'Check the last day of the month as Monday as Start
LastWeekDay = Weekday(DateSerial(Year(WeekRange), Month(WeekRange) + 1, 0), vbMonday)
If LastWeekDay > 5 Then
LastWeekDay = 5
End If
NoOfWeekDays = LastWeekDay
Else ' Week 2,3 & 4 Return 5
NoOfWeekDays = 5
End If
CalculateWorkdaysInWeek = NoOfWeekDays
End Function