SSAS DAX time intelligence previous year and calculation gives wrong value - sql

We want to show current periods sales versus previous period sales.
To show the previous period we make use of a date dimenion table and the following calculation:
CALCULATE(SalesValueGross; DATEADD(Date[Date]; -1; YEAR))
Unfortunately somehow it shows minor (decimal) differences when comparing years.
The difference get's bigger when we slice to months.
Another issue we have is that this calculation does not seem to work when comparing (for example) week 1 - 2015 with week 1 - 2014.
Any help is greatly appreciated!

When I want to get prior calendar year sales, I use the a formula such as the following:
Cal Prior Yr Sales:=if(HASONEVALUE('Sale Date'[Calendar Year]),
Calculate([Total Sales],
PREVIOUSYEAR('Sale Date'[Date])),BLANK())
The HASONEVALUE just ensures that there is only one year selected so it will know the correct previous year to retrieve.
You can make a series of calculations that will let you use one calc that determines what level of the date hierarchy you are in (assuming you have the fields available in your date table). Here is something I've used in the past, with a fiscal calendar that was different from the normal calendar.
First, the base calculations:
Sales Same Week Prior Year:=
CALCULATE([Total Sales],Filter(All('Sale Date'),
'Sale Date'[Week Key] = max('Sale Date'[Same Week Last Year])))
Sales Same Month Prior Year:=CALCULATE([Total Sales], Filter(All('Sale Date'),
'Sale Date'[Month Seq] = max('Sale Date'[Month Seq])-12))
Sales Same Quarter Prior Year:=CALCULATE([Total Sales], Filter(All('Sale Date'),
'Sale Date'[Quarter Seq] = max('Sale Date'[Quarter Seq])-4))
Sales Prior Year:=CALCULATE([Total Sales], Filter(All('Sale Date'),
'Sale Date'[Fiscal Year] = max('Sale Date'[Fiscal Year])-1))
You can hide all of those calculations and then create one last calculation and leave it visible:
Sales Same Period Last Year:=
if(HASONEVALUE('Sale Date'[Week Key]), [Sales Same Week Prior Year],
if(HASONEVALUE('Sale Date'[Month Key]),[Sales Same Month Prior Year],
if(HASONEVALUE('Sale Date'[Quarter Key]),[Sales Same Quarter Prior Year],
if(HASONEVALUE('Sale Date'[Fiscal Year]), [Sales Prior Year], BLANK()))))
You may need to add a couple of calculated fields to your date table to make it work. I have fields for: [Same Week Last Year], [Month Seq], [Quarter Seq]. Same week last year is an integer field that is yyyyww. Month Seq and Quarter Seq are just autoincrementing integers in chronological order that do not repeat.
My formula for same week last year is
=if('Sale Date'[Week Nbr] = 53, (('Sale Date'[Fiscal Year]-1) * 100) + ([Week Nbr]-1),
(('Sale Date'[Fiscal Year]-1) * 100) + ([Week Nbr]))
I did the sequence numbers in my SQL view, which is the source for the date date. As an example, if my date table starts at 1/1/2010, the month seq for Jan 2010 is 1 and the month seq for Jan 2011 is 13. The quarter seq for Q1 2010 is 1 and the quarter seq for Q1 2012 is 9.
http://www.daxpatterns.com/time-patterns/ is a good read for this topic.

Related

How to pull next 2 quarter data with a data model that doesn't have fiscal time database and company defined fiscal year

I would like to pull all orders from the current, next and next to next quarter of the time stamp. I am able to pull up current quarter data but I am not able to pull next and next+1 quarter data.
I am currently using MS SQL Server 2013.
The time stamp also appears in a weird format. for eg.20191031_FY20_Q1_Wk1 whereas [Order Close Fiscal Year Quarter Display Code] appears as 2020-Q1. So to pull current quarter data I have used below condition:
(LEFT(Time_Stamp,2)+'20'+'-'+substring(Time_Stamp,15,2)) = [Order Close Fiscal Year Quarter Display Code]
What I logically want to do is this:
(LEFT(Time_Stamp,2)+'20'+'-'+substring(Time_Stamp,15,2)) = [Order Close Fiscal Year Quarter Display Code] + 1
(LEFT(Time_Stamp,2)+'20'+'-'+substring(Time_Stamp,15,2)) = [Order Close Fiscal Year Quarter Display Code] + 2
Obviously, I came across data type conversion error. I even tried using Dateadd() function:
[Opportunity Close Fiscal Year Quarter Display Code] = DATEADD(quarter,1, cast(left(time_stamp,8) as date) )
but still I keep coming across same error.
The MOST IMPORTANT THING I would like to HIGHLIGHT is my org's Fiscal Year is not same as generic Fiscal Year. In my org, Fiscal Year begins from Oct and ends in Sep. So I am not sure how even DateAdd() function will help. I believe having a Fiscal Time table customized as per org's Fiscal Year could be of great help for me but my manager thinks the BI team won't entertain such a request.
Any help in building this query would be really great!!
You would seem to have time_stamp values whose format is not as you describe.
You should find the column values that don't convert to a date:
select time_stamp
from t
where try_cast(left(time_stamp, 8) as date) is null and time_stamp is not null
With this information, you can debug your code or the data.

Calculated member in SSAS based on custom Last Year Date (Retail calendar)

I have spent a lot of time solving this issue, but no success yet.
I have a Date dimension called [Dim Date] and in this table I have a [Date Key] which contains all the dates from '2013-07-01' to '2016-12-31'. I also have a measure called [Retail Revenue] which is a decimal number for that date. So far so easy!
We are a retail Calendar and all our calculations/comparisons are based on a retail calendar (which is a customized table in DW).
The date hierarchy in this calendar is as below (please see the screenshot):
-- retail year (e.g. 2017)
---- retail half year (e.g. 2017-H1)
------ retail quarter year (e.g. 2017-Q1)
-------- retail month (e.g. 201702) (months from 201701 to 201712)
---------- retail week (e.g. 201708) (weeks from 201701 to 201752)
------------ date key (e.g. 2016-08-22)
SCREENSHOT
We also have an attribute called "Retail Last Year Date" which shows the equivalent date of last calendar date (e.g. 2015-08-24 in the screenshot).
I need to have a calculated member showing the "Retail Revenue" for last year (based on the attribute "Retail Last Year Date"), next to the regular "Retail Revenue" for [date key].
I tried to use ParallelPeriod and Scope, and could not get the numbers properly. Probably an easy task but I am not a hero in mdx unfortunately!
Will be more than thankful if anyone please can help me out with this.
Thanks
Rez
Hopefully this helps.
This is against AdvWrks. I've created a query scoped custom measure that gets the internet sales from the year before:
WITH
MEMBER [Measures].[Internet Sales Amount LastYear] AS
(
ParallelPeriod
(
[Date].[Calendar].[Calendar Year]
,1
,[Date].[Calendar].CurrentMember
)
,[Measures].[Internet Sales Amount]
)
SELECT
{
[Measures].[Internet Sales Amount]
,[Measures].[Internet Sales Amount LastYear]
} ON 0
,
[Date].[Calendar].[Date].&[20070121]
:
[Date].[Calendar].[Date].&[20070127] ON 1
FROM [Adventure Works];
Here are the results:
Thanks for your response, but I didn't get how it uses the dimension property? because my calendar is customized and I cannot assume the last year calendar date is the same as this year. I have to read it from the dimension property "Retail Last Year Date").
Thanks

MDX to calculate difference between sales amount between 2 dates

I have a Cube with a Date dimension hierarchy (Calendar,Year,Month,Week,Day) and Measure as SalesData, would like to add a calculated measure which would give me the SalesData for the selected date and the last date of the Previous Month.
Calendar Hierarchy is as follows
Date - Dimension
Calendar - Hierarchy
Year - [Date].[Calendar].[Year]
Quarter - [Date].[Calendar].[Quarter]
Month - [Date].[Calendar].[Month]
Week - [Date].[Calendar].[Week]
Day - [Date].[Calendar].[Day]
Measures
[Sales]
New Calculated Member need to be created - say [SalesMTD]
Requirement is when a user select any date say 3 March 2016, the calculated member should give Sales as follows
[SalesMTD] = [Sales] on 3 March 2016 - [Sales] on 29 Feb 2016
Can someone please help me write an MDX query for the Calculated Measure ?
Your help much appreciated.
Please try the below code.
CREATE MEMBER CURRENTCUBE.[Measures].[Sales Last Month]
AS ([Date].[Months].CURRENTMEMBER.PREVMEMBER, [Measures].[sales])
, VISIBLE = 1 ;
Then write another calculation using the above calculations
CREATE MEMBER CURRENTCUBE.[Measures].[Sales Difference]
AS ([Measures].[Revenue]-[Measures].[Sales Last Month])
, VISIBLE = 1 ;
with member measures.SalesDataLastDaylasMonth
as
[Date].[Calendar].currentmember.firstsibling.lag(1)
//or [Date].[Calendar].currentmember.firstsibling.prevmember
select {measures.SalesData, measures.SalesDataLastDaylasMonth} on 0,
[Date].[Calendar].[Day].members on 1
from [Some Cube]
Here currentmember.firstsibling.prevmember fetches the member prior to the first day in the list of days in the current month.
Also, you can obviously create this member in a cube instead of having it query scoped like this. The syntax would be similar to the above answer.
Based upon your edit
There are multiple ways of getting to it. Below are some:
with member Measures.[SalesMTD]
as
Measures.[Sales]
-
(Measures.[Sales],Ancestor([Date].[Calendar].currentmember, [Date].[Calendar].[Month]).firstchild.firstchild)
//(Measures.[Sales],[Date].[Calendar].currentmember.parent.parent.firstchild.firstchild.lag(1))
//(Measures.[Sales],[Date].[Calendar].currentmember.parent.parent.firstchild.firstchild.prevmember)
select Measures.[SalesMTD] on 0,
[Date].[Calendar].[Day].members on 1
from [Some Cube]
The first approach is the neatest.

MDX query producing #Error as output

In my SSAS Cube, I have a measure called [Sales Total]. What I want to do is to create another measure that would give me the lowest sales figure in the last 6 months. I want this to be a moving minimum, calculated as the min of sales of every time period from the present month to 6 months back.
I wrote my MDX statement but it produces an error and I have hard time trying to figure out why. It is something to do with aggregating Date dimension members into a filter aggregate.
When i choose a single month member from the Date hierarchy, it returns the correct value. When I select multiple members from the hierarchy, as seen below, it errors out.
Any kind of help is appreciated.
WITH
MEMBER [Measures].[Min Sales Total Rolling 6 months] as '(MIN([Date].[Fiscal Month Hierarchy].currentmember.lag(6):[Date].[Fiscal Month Hierarchy].currentmember,[Measures].[Sales Total]))'
MEMBER [Date].[Fiscal Month Hierarchy].[FilterAggregate] as
'AGGREGATE({
[Date].[Fiscal Month Hierarchy].[Quarter].&[20141].&[201310],
[Date].[Fiscal Month Hierarchy].[Quarter].&[20141].&[201311],
[Date].[Fiscal Month Hierarchy].[Quarter].&[20141].&[201312],
[Date].[Fiscal Month Hierarchy].[Quarter].&[20142].&[201401],
[Date].[Fiscal Month Hierarchy].[Quarter].&[20142].&[201402],
[Date].[Fiscal Month Hierarchy].[Quarter].&[20142].&[201403],
[Date].[Fiscal Month Hierarchy].[Quarter].&[20143].&[201404],
[Date].[Fiscal Month Hierarchy].[Quarter].&[20143].&[201405],
[Date].[Fiscal Month Hierarchy].[Quarter].&[20143].&[201406],
[Date].[Fiscal Month Hierarchy].[Quarter].&[20144].&[201407]
})'
SELECT {
[Measures].[Min Sales Total Rolling 6 months]} ON AXIS(0)
FROM [My Cube]
WHERE ([Date].[Fiscal Month Hierarchy].[FilterAggregate])
As explained in this blog by one of the SSAS developers already many years ago, multi select does not work with CurrentMember. You should use
MEMBER [Measures].[Min Sales Total Rolling 6 months] as
MIN(Tail(EXISTING [Date].[Fiscal Month Hierarchy].[Fiscal Month Hierarchy].Members).Item(0).Item(0).lag(6)
:
Tail(EXISTING [Date].[Fiscal Month Hierarchy].[Fiscal Month Hierarchy].Members).Item(0).Item(0),
[Measures].[Sales Total])
instead.
EXISTING gets the set of all selected members. This is needed as there is no single CurrentMember. Then Tail gets the set consisting of the last of these members, Item(0).Item(0) converts that single element set to a member.

Clients growth over time MDX

I want to calculate the clients growth over the time.
So every day i have the total clients per state and per product subscription, and i can calculate the total for every day.
If i want to calculate the growth every day i don't have problems because i use a calculated member with
[Date].CurrentMember-[Date].PrevMember
This works pretty fine, but now i want to calculate the growth on month. So i have to sum all day growths of the month to calculate the month growth, right?
But my problem is that i'm too newbie to MDX and i can't find a way to produce that result (I want to know how many clients i have more or less over the year).
My intuition says that i need to sum all day's growth in the agregate date.
Could you help me?
If your date hierarchy has a month level above the date level (eg. Year-Month-Day), your cube will already have pre-processed this value. I would use ANCESTOR and LAG to get the data for a given day's month:
WITH MEMBER [Date].[YMD].[Current Month] AS
ANCESTOR(
[Date].[YMD].CurrentMember,
[Date].[YMD].[Month Level]
)
MEMBER [Date].[YMD].[Growth this month] AS
(
[Date].[YMD].[Current Month]
-
[Date].[YMD].[Current Month].LAG(1)
)
This will, however, only get the data from a whole-month period.
If what you're after is all the data between a particular day and the same day in the previous month, then PARALLELPERIOD is your go-to function (sidenote: not a goto statement). PARALLELPERIOD(Level, N, Member) will look at the position of Member amongst its siblings, then go to its ancestor at Level, go N members prior to that, and traverse back down to a member in the same relative position as Member.
In other words, it looks up your date in a prior month, year or whatev'.
WITH MEMBER [Date].[YMD].[One Month Ago Today] AS
PARALLELPERIOD(
[Date].[YMD].[Calendar Month],
1,
[Date].[YMD].CurrentMember
)
MEMBER [Date].[YMD].[All data since today last month] AS
(
/* The [Member]:[Member] syntax here is a range */
[Date].[YMD].[One Month Ago Today] : [Date].[YMD].CurrentMember
)
MEMBER [Date].[YMD].[Two Months Ago Today] AS
PARALLELPERIOD(
[Date].[YMD].[Calendar Month],
2,
[Date].[YMD].CurrentMember
)
MEMBER [Date].[YMD].[All data between today last month and today in the previous month] AS
(
[Date].[YMD].[Two Months Ago Today] : [Date].[YMD].[One Month Ago Today]
)
MEMBER [Date].[YMD].[Growth in the last month since the previous month] AS
(
[Date].[YMD].[All data between today last month and today in the previous month]
-
[Date].[YMD].[All data since today last month]
)
Hope this helps.
<3