I need to get the max value of a member property to use in another MDX expression.
As an example from Adventure Works I'm using the following
WITH
MEMBER DoFP AS
[Customer].[Customer].Properties("Date of First Purchase")
MEMBER MaxDoFP AS
Tail
(
NonEmpty
(
[Date].[Date].[Date]
,[Measures].[DoFP]
)
,1
).Item(0).MemberValue
SELECT
[Date].[Calendar Year].[Calendar Year] ON 0
,{
[Customer].[Customer].&[20075]
,[Customer].[Customer].&[15568]
,[Customer].[Customer].&[20285]
} ON 1
FROM [Adventure works]
WHERE
[Measures].[DoFP];
I'd like it to return June 15, 2008 for all rows/cols which is the date of first purchase for Aaron Alexander (who has the max DoFP of the customers selected) so that I can do some more calcs. Instead its giving me 31st Dec 2010 because (I assume) that's the last date in my [Date].[Date].[Date].
Not pretty:
WITH
SET X AS
{
[Customer].[Customer].&[20075]
,[Customer].[Customer].&[15568]
,[Customer].[Customer].&[20285]
}
MEMBER DoFP AS
[Customer].[Customer].Properties("Date of First Purchase")
MEMBER MaxDoFP1 AS
Max(DoFP)
MEMBER MaxDoFP2 AS
Max
(
X
,Cdate([Customer].[Customer].Properties("Date of First Purchase"))
)
SELECT
[Date].[Calendar Year].[Calendar Year] ON 0
,
X * {[Measures].[MaxDoFP1],[Measures].[MaxDoFP2]} ON 1
FROM [Adventure works];
Another option (assuming you have the ability to extend the cube structure) would be to create a measure group based on the customer dimension using a MAX aggregation function. I imagine performance would be a bit better for larger sets.
WITH
SET X AS
{
[Customer].[Customer].&[20075]
,[Customer].[Customer].&[15568]
,[Customer].[Customer].&[20285]
}
MEMBER MaxDoFP AS
Max (X,[Measures].[Customer DoFP MAX])
SELECT
[Date].[Calendar Year].[Calendar Year] ON 0
,X * {[Measures].[MaxDoFP]} ON 1
FROM [Adventure works];
Related
Overview of the table in question
I need to get a distinct count of the column Fkey_Dim_Resource_ID that has holiday to spare.
My Table consists of five columns:
Resource_Allocated_Holiday_ID (Primary Key)
Fkey_Dim_Resource_ID
Fkey_Dim_HolidayYear_ID
Fkey_Dim_Company_ID
Allocated_Holiday_Hrs_Qty
Measure:
Allocated Holiday (Hrs):= Var X= SUM([Allocated_Holiday_Hrs_Qty])
Return if(X =0; BLANK();X)
This measure below then uses the above, and the holiday spent from another metric:
Remaining Holiday (Hrs):= Var X = 'HolidayEntry Numbers'[Allocated Holiday (Hrs)] - [#Holiday Hours]
Return if(X=0;BLANK();X)
And now, I would like a metric that gives me the distinct count of Fkey_Dim_ResourceID where 'Remaining Holiday (hrs)' >0.
I have tried a lot of different stuff, but cannot seem to get it right.
test:=
ADDCOLUMNS(
SUMMARIZE('HolidayEntry Numbers'
;'HolidayEntry Numbers'[Fkey_Dim_Company_ID]
;'HolidayEntry Numbers'[Fkey_Dim_Resource_ID];
'HolidayEntry Numbers'[Fkey_Dim_HolidayYear_Id]
)
;"RemainingHoliday"; sum( [Remaining Holiday (Hrs)])
)
I would like for a distinct count of Fkey_Dim_Resource_ID that has holiday left, that takes into account the context.
Thanks in advance.
With this measure:
test4 virker når ressourcen er med:=COUNTROWS (
FILTER (
ADDCOLUMNS (
VALUES ( 'HolidayEntry
Numbers'[Fkey_Dim_Resource_ID]);
"remholiday"; CALCULATE ( [Remaining Holiday
(Hrs)] )
);
[remholiday] > 0
)
)
I get the following result:
Result of the advice1
So the metric works, when in the context of a Resource, but not when in the context of a Fkey_dim_holiday_Year_ID.
Thanks ion advance.
Resources with remaining holiday hours =
COUNTROWS ( // counts rows in a table
FILTER ( // returns a table, filtering based on predicate
// below is unique values of the column in context, as a
// one-column table
VALUES ( 'HolidayEntry Numbers'[Fkey_Dim_Resource_ID] ),
[Remaining Holiday (hrs)] > 0 // keep rows meeting this criterion
)
)
As a matter of style, you should fully qualify column names as 'Table'[Column], and never fully qualify measure references, i.e. don't prefix with table name. This conforms with all style guides I know, and helps to ensure your code is unambiguous (since both columns and measures are referenced in square brackets).
Given the MDX:
select {[Measures].[Effort], [Measures].[Count]} on columns from [Tickets]
.. How can zero (0) values for [Measures].[Effort] be filtered out from the [Measures].[Count] so that the resulting [Measures].[Count] value is reduced by the number of "Tickets" with zero (0) effort?
One would think that it would be easy to filter out values, however that's not the case. The following does not reduce the count of course because the final, single value output is naturally greater than zero (0):
select {[Measures].[Effort], FILTER([Measures].[Count], [Measures].[Effort] > 0 )} on 0
from [Tickets]
.. Also, please assume millions of tickets so placing a ticket ID on axis 1 and then filtering and then summing after the MDX result is returned would not be performant
If the performance is a matter and the following query is too slow:
With
Member [Measures].[RealCount] as
SUM(
IIF(
[Measures].[Effort] > 0,
[Measures].[Count],
Null
)
)
Select
{[Measures].[Effort],[Measures].[Count],[Measures].[RealCount]} on 0
From [Tickets]
You have to filter it out on the DWH to pre-calculate a real count.
I'm not sure of your ticket hierarchy structure so will guess that bit but I would imagine something along these lines:
WITH MEMBER [Measures].[RealCount] AS
SUM(
[Ticket].[Ticket].[Ticket Id],
Iif(
[Measures].[Effort] > 0
,1
,NULL
)
)
SELECT
{
[Measures].[Effort]
,[Measures].[Count]
,[Measures].[RealCount]
} on 0
FROM [Tickets];
If the above gives the correct result then it can be further improved by moving some of the logic to the cube script - this bit:
CREATE HIDDEN SumTicker;
[Measures].[SumTicker] = Iif([Measures].[Effort] > 0,1,NULL);
NON_EMPTY_BEHAVIOR([Measures].[SumTicker]) = [Measures].[Effort];
Then the script becomes:
WITH MEMBER [Measures].[RealCount] AS
SUM(
[Ticket].[Ticket].[Ticket Id],
[Measures].[SumTicker]
)
SELECT
{
[Measures].[Effort]
,[Measures].[Count]
,[Measures].[RealCount]
} on 0
FROM [Tickets];
I'm using SSAS OLAP and I want to apply sorting of the levels of a hierarchy.
I know that I can sort the whole hierarchy via ORDER function (I have some issues when I'm trying to apply DESC sorting on the whole hierarchy), but what I really want to achieve is sorting of a specific level. For example in the [Date].[Calendar] hierarchy (Adventure Works Cube), I want to have ASC sorting of years, DESC sorting of Quarter, ASC sorting of Months, etc.
I do not want to break the hierarchy (using BASC or BDESC), I just need them sorted on the same level. Do you have an idea if this is possible at all, as I was unable to find anything simillar?
What you can do is crossjoining the ordered correspoding attribute hierarchies. Could you verify the results of the following:
select
[Measures].[Internet Sales Amount] on 0,
Order(
[Date].[Calendar Year].[Calendar Year].MEMBERS,
[Measures].[Internet Sales Amount]
,ASC)
*
Order(
[Date].[Calendar Quarter of Year].[Calendar Quarter of Year].MEMBERS,
[Measures].[Internet Sales Amount]
,DESC)
*
Order(
[Date].[Calendar].[Month].MEMBERS,
[Measures].[Internet Sales Amount]
,ASC)
ON 1
from [Adventure Works]
Including the all members could help ([Date].[Calendar Year] instead of [Date].[Calendar Year] in case of the first crossjoin set)
Philip,
The following is a working solution, if not a really nice one:
WITH MEMBER Measures.[year] as
[Date].[Calendar].CurrentMember.Properties('Key0', typed)
MEMBER Measures.[qtr or mth] as
[Date].[Calendar].CurrentMember.Properties('Key1', typed)
MEMBER Measures.[sortKey] as
CASE
WHEN [Date].[Calendar].CurrentMember.Level IS [Date].[Calendar].[Calendar Year] THEN
Measures.[year] * 1000
WHEN [Date].[Calendar].CurrentMember.Level IS [Date].[Calendar].[Calendar Quarter] THEN
Measures.[year] * 1000 + (5 - Measures.[qtr or mth]) * 100
ELSE // month
Measures.[year] * 1000 + (4 - Int((Measures.[qtr or mth] - 1) / 3)) * 100 + Measures.[qtr or mth]
END
SELECT {Measures.[year], Measures.[qtr or mth], Measures.[sortKey]}
ON COLUMNS,
Order(
[Date].[Calendar].[Calendar Year]
+
[Date].[Calendar].[Calendar Quarter]
+
[Date].[Calendar].[Month]
,
Measures.[sortKey]
,BASC
)
ON ROWS
FROM [Adventure Works]
The measures on the columns are just for clarification how it works. And the main logic is in the generation of the sortKey measure which generates an integer key as follows: four digits for the year, one digit for the backwards quarter (Q4 -> 1, ... Q1 -> 4), two digits for the month. Then, using that, it is straightforward to call Order to return the sorted set.
It turned out that it is impossible to achieve the desired effect - there's no such MDX query that can sort different levels with different sorting type. More information is available in this thread.
I can't find out a way, how to sort my query, this is the simple query:
SELECT {[Measures].[IB]}
ON COLUMNS,
{[Dim_Product_Models_new].[PLA].members } *
{[Dim Dates_new].[Date Full].&[2013-02-01]:[Dim Dates_new].[Date Full].&[2014-01-01]}
ON ROWS
FROM [cub_dashboard_spares]
The think is, I would get a result for 6 PLAs combined across 12 months (72 rows in total), however it is sorted alphabetically upon PLA.
What i need, is to sort the PLAs based on a measure in last month (2014-01-01 in this case).
Is there any way to perform this task so that the groupping (PLAs, Dates from 2013-02 to 2013-12) is perserved, but only the order of my PLAs is different. (PLA with highest measure in last month would be first, and so on)
Thank you very much for any kind of help
Just put the sorted set on the rows, using the Order function. The third parameter of this function is DESC if you want to sort within each hierarchy level, but still want to get parents before children (like ALL before the single attribute members), or BDESC if you want to sort across all levels.
SELECT {[Measures].[IB]}
ON COLUMNS,
Order({[Dim_Product_Models_new].[PLA].members },
([Measures].[IB], [Dim Dates_new].[Date Full].&[2014-01-01]),
DESC)
*
{[Dim Dates_new].[Date Full].&[2013-02-01]:[Dim Dates_new].[Date Full].&[2014-01-01]}
ON ROWS
FROM [cub_dashboard_spares]
The order function over a crossjoin should preserve the initial order of the first set so reversing the order of the tuple will do the job:
SELECT
{
[Measures].[IB]
} ON COLUMNS,
order(
{[Dim Dates_new].[Date Full].&[2013-02-01]:[Dim Dates_new].[Date Full].&[2014-01-01]} *
{[Dim_Product_Models_new].[PLA].members } ,
[Measures].[IB],
desc
) ON ROWS
FROM [cub_dashboard_spares]
If you want to preserve the oder of appearance of the column labels, you can use the generate function like in the following example from the AW cube:
SELECT
{[Measures].[Internet Sales Amount]} ON 0
,Generate
(
{[Customer].[Country].&[Australia]:[Customer].[Country].&[United Kingdom]}
,(
Order
(
[Date].[Calendar Year].[Calendar Year].MEMBERS
,(
[Customer].[Country].CurrentMember
,[Measures].[Internet Sales Amount]
)
,DESC
)
,[Customer].[Country].CurrentMember
)
) ON 1
FROM [Adventure Works];
Philip,
I tried to create a calculated member for displaying profit for each product, but I got an error on the "select". Can anyone help me out with this since I am newbie in this?
CALCULATE;
CREATE MEMBER CURRENTCUBE.[Measures].Profit_Per_Produkt
AS Select [Measures].[Vinst] on columns,
[Dim Produkt].[Artikelnr].[Artikelnr] on rows
from [Elektronikkedja],
FORMAT_STRING = "Percent",
VISIBLE = 1 , ASSOCIATED_MEASURE_GROUP = 'Fact Köp' ;
A calculated member you should contains a calculate expression as:
([Measures].[Internet Sales-Sales Amount] -
[Measures].[Internet Sales-Total Product Cost]) /
[Measures].[Internet Sales-Sales Amount]
See on technet Defining Calculated docs a some samples.