Adding complex measures in MDX - mdx

I have successfully added basic sum/count/etc.. simple measures, but have no idea how to add more complex one.
Let's assume that data structure represent tracks with goods and have next structure:
date
id_track
id_articte
amount
cost
And want to calculate next measures:
average item price, calculated as sum(cost) / sum(amount)
average track cost. It's average between sum(cost) for whole tracks. Sql expression looks like sum(cost) / count(distinct id_track)
What is the right way to add this measures to my cube, in case i will need them in Excel over XMLA?

Complex calculation are solved using what we call in MDX 'calculated measures'.
Calculated Measures support the whole power of MDX language. You can see more information about Calculated Measures here. They are very powerful and over 100 functions are supported (function list).
If you want to define a calculated measure once per schema I'd advise defining them in Advanced/Scripts in the Builder UI tab. You can first check validity in the MDX IDE and once validated move them to the Script.

average item price, calculated as sum(cost) / sum(amount)
This would look something like the following:
WITH MEMBER [Measures].[AvgPrice] AS
AVG(
EXISTING([Item].[Item].MEMBERS)
,[Measures].[COST]
)
...
Or
WITH MEMBER [Measures].[AvgPrice] AS
[Measures].[COST]
/
[Measures].[AMOUNT]
...
average track cost. It's average between sum(cost) for whole tracks.
Sql expression looks like sum(cost) / count(distinct id_track)
WITH MEMBER [Measures].[AvgTrackCost] AS
AVG(
EXISTING([TrackItem].[TrackItem].MEMBERS)
,[Measures].[COST]
)
...
I've had to guess that the following exist within your cube:
[Measures].[COST]
[Measures].[AMOUNT]
[Item].[Item].MEMBERS
[TrackItem].[TrackItem].MEMBERS

Related

About Aggregage/Sum column in SSAS Cube

I am working on a simple project using SSAS Cube on SQL Server 2016 and SSDT2015. DW_Orders database is from Orders DW. The table factor orders contains attributes UnitPrice, Quantity and Discount with the calculation member TotalSale defined as [Measures].[Unit Price][Measures].[Quantity](1-[Measures].[Discount]), well as the FK members CustomerID and OrgID. I want to get the TotalSale based on Country-City Hierarchy from dimension dimCustomers. But I got the following result:
enter image description here
it is obvious that the UnitPrice, Quantity and Discount have been summed under the city or country so that we got wrong and negative result of TotalSale from the calculation. Tried in the Edit Measure, cannot get what I expect. Need your help on some settings, thanks.
You need to edit the aggregation type for the 2 measures(discount and unit price). By default, the type is SUM, you need to use Average. To do that, go to the measure group, select the measure and access its properties to set the aggregation.

Calculated Measures - Beginning balance

I am a newb when it comes to MDX so please bear with me as I try to explain this.
I have cube with a measure for cost [Measure].[Cost] and the query is setup with a time parameter to obtain the total cost up to that point in time. #ToAcctDate and is used in the FROM statement as such:
FROM (SELECT (STROSET(#ToAcctDate, CONSTRAINED)) ON COLUMNS
but I would like to get the PREVIOUSMEMBER if possible and to something like
WITH
MEMBER [Measures].[PriorPeriod] AS
SUM( (STROSET(STROSET(#ToAcctDate, CONSTRAINED).PREVMEMBER), [Measures].[Cost])
so that I can then have both the YTD costs as of #ToAcctDate and the YTD Costs at the beginning of the period [Measures].[PriorPeriod] in the same query without unions. is this possible? and if so, is this the right approach?
Maybe along the lines of this?
HEAD will find the first member of the set which you can then apply PREVMEMBER to:
SUM(
HEAD(STROSET(#ToAcctDate, CONSTRAINED)).ITEM(0).ITEM(0).PREVMEMBER)
, [Measures].[Cost]
)

MDX: Make Measure Value 0 based on flag

Would much appreciate any help on this.
I have a measure called "Sales" populated with values, however i am trying to turn the "Sales" value to 0, whenever the "Sales Flag" is set to 0.
Important Note: The Sales Flag is based on Date (lowest level of detail).
The difficulty that i am really experiencing and cant get a grip on, is how i am trying the display the MDX outcome.
As explained above, i would want to make the "Sales" value 0 whenever we have a 0 in the "Sales Flag" (which is based on the Date), but when I run the MDX Script I would wan't on the ROWS to NOT display the Date, but instead just the Week (higher Level to Date), as below shows:
I really have spent hours on this and can't seem to understand how we can create this needed custom Sales measure based on the Sales Flag on the date level, but having the MDX outcome display ROWS on Week level.
Laz
You need to define the member in the MDX before the select. Something like that:
WITH MEMBER [Measures].[Fixed Sales] as IIF([Sales Flag].currentMember=1,[Sales], 0)
SELECT [Measures].[Fixed Sales] on 0, [Sales Flag] on 1 from [Cube]
I am writing the code without SSAS here so it might not be the 100% correct syntax but you can get the general idea ;)
You can add the iif in the SELECT part but I find creating member to be the cleaner solution.
SELECT IIF([Sales Flag].currentMember=1,[Sales], 0) on 0, [Sales Flag] on 1 from [Cube]
If you have a control over the cube in SSAS you can create a calculated member there and you can access it easier.
Glad to hear if Veselin's answer works for you, but if not...
Several approaches are also possible.
Use Measure expression for Sales measure:
Use SCOPE command for Day level (if it's Key level of Date dimension). If it's not a key level you have to aggregate on EVERY level (week, year etc) to emulate AggregateFunction of Sales measure but with updated behavior for one flag:
SCOPE([Date].[Your Date Hierarchy].[Day].members,[Measures].[Sales]);
THIS=IIF([Sales Flag].CurrentMember = 1,[Measures].[Sales],0);
END SCOPE;
Update logic in DSV to multiply Sales column by SalesFlag. This is the easiest way from T-SQL perspective.

MDX (calculations) - count all clients accounts

I would like to count all clients accounts in my cube. I have created new calculation and I wrote a query in MDX langugage like:
COUNT(
[Client].[IdClient]
)
but when I would like to know how many accounts have, I always get '1' value instead e.g. '6000'.
This is my first time with MDX and OLAP Cubes.
What I supposed to do to get correct value?
Try this:
COUNT(
EXISTING [Client].[IdClient].[IdClient].Members
)
If you aren't happy with the performance of that then delete the calculated measure and replace it with a measure group built on the Client table. Build a Count measure.

calculating new measures in SSAS

I have a cube in my sql server analysis service (2012) project. One of my measures is withdrawn money from ATM. Now I want to have a new calculated measure that show me the growth of withdrawn money today toward to last day. It is a dynamic calculated measure.
Is there any solution for doing this work?
What you are looking for is most probably called a KPI = key performance indicator. Look here for information about how to add the metric you need.
if you want to show growth based on last value, for example today I Withdrew 10% less than yesterday, yo ucan use KIPs
if you want to show how much you Withdrew so far, you should use calculatins like YTD (year to date)
You should use KPI to build your measure.
Open your SSAS project in Visual Studio and double click on your cube.
In the KPI tab there is a panel with some samples of KPI using parallel periods.
This is an example to create an operating margin accross two periods :
IIf
(
KPIValue( "Gross Profit Margin" ) >
( KPIValue( "Gross Profit Margin" ),
ParallelPeriod
(
[<<Time Dimension Name>>].[<<Time Hierarchy Name>>].[<<Time Year Level Name>>],
1,
[<<Time Dimension Name>>].[<<Time Hierarchy Name>>].CurrentMember
)
), 1, -1
)