Dimension distinct count SSAS within the context of other dimensions - sql-server-2012

I have this MDX;
CREATE MEMBER CURRENTCUBE.[Measures].DistinctOrderCount<br/>
AS
DistinctCount([Order].[Order Id].[Order Id] - [Order].[Order Id].[1]),<br/>
FORMAT_STRING = "#,##0;-#,##0",
VISIBLE = 1, ASSOCIATED_MEASURE_GROUP = 'Fact Sales';
I am trying to do a distinct of orders (except Order Id=1) within the context of other dimensions in my fact table. For example, distinct order count by dim customers, dim city, dim state etc. but I am not able to achieve this. When I view my measure on a report, I get distinct count of order dimension which is 21 being displayed on all rows of customers.

This is the best way I solved this and I am happy with the results. Hope this may help others. The idea is, create a cube measure with aggregation type Distinct Count and set column binding on the column you want distinct count on. Then use the below MDX to filter out the dummy Order Id's from your distinct count.
create member currentcube.[Measures].OrderCount<br/>
as<br/>
distinctcount
(
existing
CROSSJOIN
(
Except([Orders].[Order Id].[Order Id], [Orders].[Order Id].&[1]),
[Measures].[Order Count]
)
),<br/>
FORMAT_STRING = "#,##0;-#,##0",
VISIBLE = 1, ASSOCIATED_MEASURE_GROUP='Order Count';

Related

SSAS : Filter Cube

I have dimension and fact table. The dimension is PATIENTDBOID meanwhile the fact table is Total_Admissions.
Now, I want to filter for Patient that Admission >1
Can someone help me how. ?
You Can use Filter Function to Apply filter on Measures with Logical Expression.
Since I don't know Exact Dimension Name, You can try something like below.
0 - Represents COLUMNS
1 - Represents Rows
SELECT [Measures].[Total_Admissions] ON 0,
FILTER(
[Patient].[Patient].[PatientDBOID].MEMBERS
, [Measures].[Total_Admissions]>1)
ON 1
FROM [Cube Name]

Calculated SSAS Member based on multiple dimension attributes

I'm attempting to create a new Calculated Measure that is based on 2 different attributes. I can query the data directly to see that the values are there, but when I create the Calculated Member, it always returns null.
Here is what I have so far:
CREATE MEMBER CURRENTCUBE.[Measures].[Absorption]
AS sum
(
Filter([Expense].MEMBERS, [Expense].[Amount Category] = "OS"
AND ([Expense].[Account Number] >= 51000
AND [Expense].[Account Number] < 52000))
,
[Measures].[Amount - Expense]
),
VISIBLE = 1 , ASSOCIATED_MEASURE_GROUP = 'Expense';
Ultimately, I need to repeat this same pattern many times. A particular accounting "type" (Absorption, Selling & Marketing, Adminstrative, R&D, etc.) is based on a combination of the Category and a range of Account Numbers.
I've tried several combinations of Sum, Aggregate, Filter, IIF, etc. with no luck, the value is always null.
However, if I don't use Filter and just create a Tuple with 2 values, it does give me the data I'd expect, like this:
CREATE MEMBER CURRENTCUBE.[Measures].[Absorption]
AS sum
(
{( [Expense].[Amount Category].&[OS], [Expense].[Account Number].&[51400] )}
,
[Measures].[Amount - Expense]
),
VISIBLE = 1 , ASSOCIATED_MEASURE_GROUP = 'Expense';
But, I need to specify multiple account numbers, not just one.
In general, you should only use the FILTER function when you need to filter your fact table based on the value of some measure (for instance, all Sales Orders where Sales Amount > 10.000). It is not intended to filter members based on dimension properties (although it could probably work, but the performance would likely suffer).
If you want to filter by members of one or more dimension attributes, use tuples and sets to express the filtering:
CREATE MEMBER CURRENTCUBE.[Measures].[Absorption]
AS
Sum(
{[Expense].[Account Number].&[51000]:[Expense].[Account Number].&[52000].lag(1)} *
[Expense].[Amount Category].&[OS],
[Measures].[Amount - Expense]
),
VISIBLE = 1 , ASSOCIATED_MEASURE_GROUP = 'Expense';
Here, I've used the range operator : to construct a set consisting of all [Account Number] members greater than or equal to 51000 and less than 52000. I then cross-join * this set with the relevant [Amount Category] attribute, to get the relevant set of members that I want to sum my measure over.
Note that this only works if you actually have a member with the account number 51000 and 52000 in your Expense dimension (see comments).
An entirely different approach, would be to perform this logic in your ETL process. For example you could have a table of account-number ranges that map to a particular accounting type (Absorption, Selling & Marketing, etc.). You could then add a new attribute to your Expense-dimension, holding the accounting type for each account, and populate it using dynamic SQL and the aforementioned mapping table.
I don't go near cube scripts but do you not need to create some context via the currentmember function and also return some values for correct evaluation against the inequality operators (e.g.>) via the use of say the membervalue function ?
CREATE MEMBER CURRENTCUBE.[Measures].[Absorption]
AS sum
(
[Expense].[Amount Category].&[OS]
*
Filter(
[Expense].[Account Number].MEMBERS,
[Expense].[Account Number].currentmember.membervalue >= 51000
AND
[Expense].[Account Number].currentmember.membervalue < 52000
)
,
[Measures].[Amount - Expense]
),
VISIBLE = 1 , ASSOCIATED_MEASURE_GROUP = 'Expense';
EDIT
Dan has used the range operator :. Please make sure your hierarchy is ordered correctly and that the members you use with this operator actually exist. If they do not exist then they will be evaluated as null:
Against the AdvWks cube:
SELECT
{} ON 0
,{
[Date].[Calendar].[Month].&[2008]&[4]
:
[Date].[Calendar].[Month].&[2009]&[2]
} ON 1
FROM [Adventure Works];
Returns the following:
If the left hand member does not exist in the cube then it is evaluated as null and therefore open ended on that side:
SELECT
{} ON 0
,{
[Date].[Calendar].[Month].&[2008]&[4]
:
[Date].[Calendar].[Month].&[1066]&[2] //<<year 1066 obviously not in our cube
} ON 1
FROM [Adventure Works];
Returns:

Filtering dimensions in MDX inside a SUM

I am new to MDX expressions and I am trying to create one that sums the value of a given measure filtered by dimensions.
In my database I have several different dimensions that have the same name: "Answer". To sum them up, I have created the query below:
WITH MEMBER Measures.Total as SUM ({[Activity].[Activity].&[14], [Activity][Activity].&[22]},
[Measures].[Activity time])
SELECT NON EMPTY [Measures].[Total] on COLUMNS from [My Analytics]
This query works, however I had to use the "&[14]" and "&[22]" statments that correspond to two different "Answer" dimensions.
Since I have more than two dimensions with the same name, is there a way to rewrite the query above in a way that I would select all these dimensions without having to add their unique ID? For example, I would re-write the query as something like this:
WITH MEMBER Measures.Total as SUM ({[Activity].[Activity].&["Answer"]},
[Measures].[Activity time])
SELECT NON EMPTY [Measures].[Total] on COLUMNS from [My Analytics]
Is this possible?
Thanks!
You can use the Filter function as following:
with
set [my-answers] as
Filter( [Activity].[Activity].members,
[Activity].[Activity].currentMember.name = 'Answer'
)
member [Measures].[Total] as Sum( [my-answers] )
...

SSAS -> MDX -> Creating a column percentage within my query based on counts

SELECT
NON EMPTY {[Measures].[Fact Order Count]}
ON COLUMNS,
{ ([Front Manager].[Front Manager Id].[Front Manager Id].ALLMEMBERS * [Order Type].[Order Type].[Order Type].ALLMEMBERS ) }
ON ROWS
FROM
[TEST_DW] CELL PROPERTIES VALUE
So, I have three columns in the output:
Front Manager, Order Type, Order Count
The above query shows me the counts for each manager and order type combination. I need a fourth column which would be a percentage of the types of orders for each front manager.
So, if there are four types of orders (A, B, C, D), and a manager had 25 of each order totaling 100. The fourth column would read 25%.....
I have scoured the web on how to do this, but have really come up short on this one. Any direction on this would be greatly appreciated, I am definitely new to MDX. Thanks.
What you're looking for are MDX Calculated members.
Let's assume the member for order A is called : [Order Type].[Order Type].[Order A] and we want to calculate the percentage from the total.
WITH
MEMBER [Order A] AS ([Order Type].[Order Type].[Order A],[Measures].[Fact Order Count]) / ([Measures].[Fact Order Count]) , FORMAT_STRING = 'Percent'
SELECT
{[Measures].[Fact Order Count],[Measures].[Order A]} on 0
...
What is important in the calculated members is that you can evaluate any MDX tuple (e.g ([Order Type].[Order Type].[Order A],[Measures].[Fact Order Count]) ). This changing if needed the values coming from the pivot axis (defined in on 0 and on 1..). Note you can add calculated members for the measures as well as the other dimensions.

In MDX how can I filter a dimension/axis based on a TopCount

I have cube which contains geographic sales data. I want to pull sales of product items from all stores, based on the top 5 sellers from an arbitrary known store (BTW this is a simplified version of the real issue).
In sql (shame on me) this would be
select StoreId, ProductId, Sales from cube where ProductId in
(select top 5 ProductId from cube where Store = #Store order by Sales desc)
You can use the Topcount function for this. Provided you have dimensions named Product and Store and a measure named [Sales]:
Select [Measures].[Sales] On Columns,
CrossJoin([Store].Members,Generate(Topcount(Crossjoin({[Store].#[<StoreId>]},[Product].Members),5,[Measures].[Sales]),[Product].CurrentMember)) On Rows
From [Yourcube]
Replace <StoreId> with the specific store you're interested in. Generate will loop through the top 5 found for the specific store and return only the Product members. This result is then crossjoined with all the stores.
This will extract the top 5 products for your-store in ROWS axis and then select the [Sales] of these products according to the defaultMember of the [Store] dimension. In case [Store] defaultMember is the root of an aggregatable hierarchy this should give the sales of each product over all the stores.
SELECT
[Measures].[Sales] ON 0,
TopCount( [Store].[your-store] * [Product].Members ), 5, [Measures].[Sales] ) ON 1
FROM [your-cube]