I built a SSRS 2005 report on a SSAS 2005 cube. The report has start date and end date parameters from Time dimension. I need to set the default values to be last Sunday and last Saturday separately. (financial week is from Sunday to Saturday)
E.g.
Start date: [Time].[Day].&[20140309]
End date: [Time].[Day].&[20140315]
How can I do it dynamically? I mean for this week is above dates, but for next week, it should be 16 March, 22 March. I know how to do it in T-SQL, which will involve some calculation with system date, but MDX?
You can use some VBA Date functions available in MDX:
StrToMember('[Time].[Day].&['
+ Format(DateAdd('d', - DatePart('w', Now(), 1), Now()), 'yyyyMMdd')
+ ']'
)
should give you the last Saturday before today, and
StrToMember('[Time].[Day].&['
+ Format(DateAdd('d', - DatePart('w', Now(), 1) - 6, Now()), 'yyyyMMdd')
+ ']'
)
the last Sunday before that.
The second argument of DateAdd('d', ...) is the number of days to add. And as this is negative here, we go back in time that many days. DatePart('w', ...) returns the weekday number (Sunday = 1, Monday = 2, ...). Thus, if you subtract "weekday number" days from today, luckily you are already at last Saturday. And subtracting six more days, you arrive at the last Sunday before that.
Related
How do I get the first and last day of the previous year in SSRS for default dates
tired wth DATEADD function but getting an error
You can use DATESERIAL() to do this easily
DateSerial just take 3 integer values (year, month, day) to return a date.
First day
=DateSerial( year(today()) - 1, 1, 1)
Last Day
=DateSerial( year(today()) - 1, 12, 31)
You don't show what you tried so we can't explain what you are doing wrong.
If I needed to get the 1st day of the previous year, I would take the current year, subtract the number of days from 1 and then subtract a year.
With DATEADD, the first day of last would be:
=DATEADD("yy", 1, DATEADD("d", 1 - DATEPART("dy", TODAY), TODAY))
While the last day is actually simpler:
=DATEADD("d", 0 - DATEPART("dy", TODAY), TODAY)
This code quit working in 2021 after working in 2020:
SELECT name, SUM(CASE WHEN YEARWEEK(prod_date) = YEARWEEK(now()- INTERVAL 1 WEEK) THEN gas_prod ELSE NULL END) AS LastWeek FROM daily_prod GROUP BY name
The code now calculates a larger number than occurred last week. Any reason why a new year would cause this code to work differently?
First, using the sum( case/when ) is a bad choice here. Your query is going against your ENTIRE daily_prod table, EVERY RECORD, but only summing when within the given yeardate() period based on whatever the current date is. Instead of doing that, build out a WHERE clause to just get the records you care about. The YearWeek() function is based on a Sunday to Saturday week schedule. So, for example this week is from Jan 31 at 12:00am (midnight) up to, but not including Feb 7th at 12:00am midnight. This includes everything up to Feb 6th at 11:59:59pm.
So, by doing embedded MySQL variables you can build as a "from" table alias as I will show. First, lets get whatever the current NOW() is which is inclusive of hour/minute/second and strip down to just the date portion. Ex: 2021-02-04 # 01:42am truncates down to just 2021-02-04 12:00am
select cast( now() as date )
From that, now, we need to go to the first of the week, represented as Sunday. For this, we use the day of the week and subtract 1 so it is a zero-based value where Sunday = 0, Saturday = 6. So Thursday, normally returns 5, subtract 1 = 4. February 4 - 4 days = Jan 31 which is the first of the current week.
select date_sub( [result of sql above], interval dayofweek( [result of sql above] ) -1 day )
Now, since you want the entire week of data, in this scenario, your data would be from Jan 31 at 12:00am in the morning up to Feb 6th (Saturday) at 11:59:59PM. So, take the above beginning of the week and add 1 week to it bringing you to Feb 7th.
select date_add( [result of 2nd query], interval 1 week )
Yes, this is intentional because now in your final query you can query LESS THAN Feb 7th.
So, by using a where on your data source, you only get those records, AND, if your table has an index on the transaction date, can be optimized for the query. To use inline variables, we can just use the results of these as part of the query such as:
SELECT
dp.name,
SUM( dp.gas_prod ) CurrwntWeekGas
FROM
daily_prod dp,
( select
-- first, variable #nd = Now as a date only
#nd := cast( now() as date ),
-- from the #nd, subtract 0-based day of week
-- example: Thursday is 5th day of week -1 = 4 days to subtract
#fow := date_sub( #nd, interval dayofweek( #nd ) -1 day ),
-- finally from the first of the week, add 1 week to the END point for the query
#nextWeek := date_add( #fow, interval 1 week )
) sqlvars
where
-- only grab records greater or equal to the first day of the week
dp.prod_date >= #fow
-- and ALSO LESS then the the beginning of NEXT week
AND dp.prod_date < #nextWeek
GROUP BY
dp.name
So, as the from clause alias "sqlvars" is processed, it creates the 3 "#" variables to define the beginning of week and beginning of NEXT week values. Those can then be applied to the where clause and limit just the records you need, not the full table.
If you really want the results of the prior week from the week you are in... Ex: the total from Jan 24th to Jan 30th since the current week has not completed, then just change your dayofweek() -1 to dayofweek() -8 to get the entire prior week, not the CURRENT week you are in the middle of now.
I am creating a package which will store a report's generation date. on basis of that date need to derive the next Wwednesday date.
Ex: report date is 11/11/2019 so wed date should be 13/11/2019.
This Derived Column Expression should provide the next Wednesday's date.
DATEADD("DAY",((1 + DATEDIFF("DAY",(DT_DATE)"1/1/1970",GETDATE())) / 7) * 7 + 6,(DT_DATE)"1/1/1970")
Parts (inside out).
Days since 1/1/1970 + 1.
(Divide by 7) (Implicit Cast to Int) (Multiple by 7) will round it to last Thursday.
When added days back to 1/1/1970 (+6 days more) will move to next occurring Wednesday.
Notes
Without the initial 1 day offset, If GETDATE() is a Wednesday, the result will be GETDATE()'s date.
GETDATE() can be swapped out with GETUTCDATE() or a date Variable as needed.
The +6 can be moved back to +5 if a Tuesday is desired.
I need to construct a data parameter in SSRS 2008 where if the current week number is 1 then I use the first day of the previous month and if not then I use the current day.
I.e. today is week 4 therefore would utilize today's date
If today was march 2, then the week would be week 1 and I would utilize the first of the previous month, feb 1
note: weeks must follow calendar weeks.
Thanks in advance for your assistance
You can set the parameter default using the following expression:
=IIf(Day(Today()) <=7
and DatePart(DateInterval.WeekDay, Today(), FirstDayOfWeek.Monday)
>= DatePart(DateInterval.WeekDay, DateSerial(Year(Today()), Month(Today()), 1), FirstDayOfWeek.Monday)
, DateAdd(DateInterval.Month, -1, DateSerial(Year(Today()), Month(Today()), 1))
, Today())
So:
If today is one of the first seven days of the month, and the day of the week number is >= the day of the week of the first of the month
=> First week, so use the first day of the previous month
=> Else use the current date.
We have customers that currently have defined weeks starting either on Sat, Sun or Monday. Came across these DATE_FORMAT options which nicely handle the week starting on Sunday and Monday but can't find a way to do same for week starting on Saturday. Any suggestions?
%U Week (00..53), where Sunday is the first day of the week
%u Week (00..53), where Monday is the first day of the week
I had a similar issue: I needed to calculate week numbers based on the following rules:
Week starts on Friday
The remainder days of an year (all the days after the last Friday of the year that do not complete a week) should be counted in the
first week of the next year.
For example:
27/12/2012 (Thursday) should be Week 52 of 2012
28/12/2012 (Friday) should be Week 1 of 2013
Week 1 2013 goes from 28/12/2012 to 3/1/2013
I made this statement that calculates both the YEAR and WEEKNUMBER based on these rules that you can easily adapt to your circunstance:
SELECT IF(ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7) > 52, YEAR(current_date)+1, YEAR(current_date)),
IF(ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7) > 52, 1, ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7));
The tricky part is just this expression:
ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7)
The rest (If clauses) are just for adapting the result of the expression to make year+1 and week = 1 on week 53.
I'll try to explain the expression as best as I can. The following expression gives you the week number pure simple (the day of the year divided by 7 days in a week rounded up):
ceil(( dayofyear(current_date))/7)
But now you want to make it start on Friday (or any other day). To do this you need to add to the current day, the days of the first week that were part of the previous year (it's like your current actually started a few days before, because your first week contains days from the previous year).
This expression calculates that offset based on the weekday on Jan/1:
dayofweek(date_format(current_date, '%Y-01-01'))+OFFSET
The offset is the difference between 7 and the weekdaynumber you want the week to start:
0 for Saturday
1 for Friday
2 for Thursday
3 for Wednesday
...
So now you just have to add it to the previous one resulting in the above mentioned expression that calculates the week numbers starting on any weekday and assuming week 1 to start on the previous year:
ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+OFFSET )/7)
Then I just added an IF that turns week 53 into week 1 and another to add 1 to the year if it's week 53.
It took me a while to think on this question.
ISO standard defines the first week to start on Monday and contain 4th day of the year.
MySQL's functions provide much more choices.
date_format() flags %U and %u are using notation where first week is the one where Sunday or Monday is first met. As this is not according to the ISO, I will provide both variants.
If you want to count week numbers starting from Saturday and first year's week is the one containing Saturday, you can use one of the following expressions:
SELECT sign(dayofweek(current_date) - 7) + ceil(dayofyear(current_date)/7);
SELECT ceil((dayofyear(current_date)+
(dayofweek(date_format(current_date, '%Y-01-01'))%7-7))/7);
If first year's week is the one where 4th day of the year falls into, use:
SELECT ceil((dayofyear(current_date)+
(dayofweek(date_format(current_date, '%Y-01-04'))%7-4+1))/7);
The very first expression is quite straightforward.
I will elaborate on the 2nd and 3rd ones. I calculate week number by taking current day of the year, dividing by 7 and ceiling up, quite simple. Week number needs to be adjusted based on the situation at the beginning of the year though.
for the first case (first week starts with the first Saturday), I take day-of-week for the Jan/1 of the year in subject, make Saturday as the day 0 and then adjust day-of-year by the difference. This this makes all days before first saturday yielding negative adjustment number and it ceils up to zero;
for the second case (first week is the one where 4 day of the year falls in), I take day-of-week for the Jan/4 of the year in subject, make Saturday as the day 0. The -4+1 formula gives adjustment to the first Saturday before Jan/4, +1 is used as days of the year starts from 1, not from 0. Negative adjustment means 1st day of the year is not in the first week of the year.
Here're some test dates on the SQL Fiddle.
If you want to count weeks from any other day, you just have to change the formula, making that day being 0 in the sequence. Say, to count weeks starting from Wednesday, use:
SELECT ceil((dayofyear(current_date)+
((dayofweek(date_format(current_date, '%Y-01-04'))+3)%7-4+1))/7);
+3 is used as it complements dayofweek() value for Wednesday to the 7.
Make an adjustment based on DAYOFWEEK().