MDX Record Count - mdx

Can any one tell me how to get the record count that is a result of a MDX query?I have tried various methods and I haven't really got a solution for that.I am a beginner in MDX queries.

WITH
MEMBER [Measures].[amount] as
COUNT(
[your_dimension].[your_dimension_property].Members
)
SELECT {[Measures].[amount]} ON COLUMNS
FROM [your_awesome_cube]
A code like this will return to you the amount of members in your dimension, the COUNT method have this syntax
Count(Set_Expression [ , ( EXCLUDEEMPTY | INCLUDEEMPTY ) ] )
so you can do a lot of things, like filter your search

Create a measure in the cube that is a count or distinct count.

1) open the cube
2) Right click on the fact table on which that measure sits
3) Select New Measure...
4) Dropdown the list and select the aggregation
5) In the source column section, select the column you want the aggregation on (if u cant find it, click on show all columns on the bottom- this depends on what you are aggregating)

with member
Measures.Counts as
[your_dimension].[your_dimension_property].Children.COUNT
select Measures.Counts on 0
FROM [your_awesome_cube]

When you say record count, you basicly are saying the valid combinations of your row axis.
Lets take a basic example, the query returns 3637 rows, of which 1 row is parctically the column name row.
select [Measures].[Sales Amount] on columns,
(
[Customer].[Country].[Country],
[Product].[Product].[Product]
) on rows
from [Adventure Works]
Now to get the row count without running the query, lets put the combinations in count function and put the count function in a runtime measure
This Returns 3636 row.
with member [Measures].[rowCount]
as
count(([Customer].[Country].[Country],[Product].[Product].[Product]))
select [Measures].[rowCount] on columns from [Adventure Works]
Notice I have not eleminated the null combinations on rows. Lets do that next
The query returns 2101 rows , again one row from column headers.
select [Measures].[Sales Amount] on columns,
non empty
(
[Customer].[Country].[Country],
[Product].[Product].[Product]
) on rows
from [Adventure Works]
Now lets count the rows
This returns 2100 rows.
with member [Measures].[rowCount]
as
count(nonempty(( [Customer].[Country].[Country],[Product].[Product].[Product])
,{[Measures].[Sales Amount]}
))
select [Measures].[rowCount]
on columns from [Adventure Works]
Till now we had measure from just one measure group, now lets try with multiple measure groups.
select {[Measures].[Sales Amount],[Measures].[Internet Sales Amount]} on columns,
non empty
(
[Customer].[Country].[Country],
[Product].[Product].[Product]
) on rows
from [Adventure Works]
//Cell set consists of 2101 rows and 3 columns.
//Wrong way
with member [Measures].[rowCount]
as
count(nonempty(( [Customer].[Country].[Country],[Product].[Product].[Product])
,{[Measures].[Internet Sales Amount]}
))
select [Measures].[rowCount] on columns from [Adventure Works]
//935
//Right way
with member [Measures].[rowCount]
as
count(nonempty(( [Customer].[Country].[Country],[Product].[Product].[Product])
,{[Measures].[Sales Amount],[Measures].[Internet Sales Amount]}
))
select [Measures].[rowCount]
on columns from [Adventure Works]
///2100
Notice when we use just a single measure the result may not be correct . If the measure we use has a null value then the combination would be removed. Where as in our rows the other measure will ensure that the combination appears.
Now Lets add a filter to the picture.
select {[Measures].[Sales Amount],[Measures].[Internet Sales Amount]} on columns,
non empty
filter(
(
[Customer].[Country].[Country],
[Product].[Product].[Product]
)
,[Measures].[Internet Sales Amount]>5000) on rows
from [Adventure Works]
//Cell set consists of 586 rows and 3 columns.
//Wrong way
with member [Measures].[rowCount]
as
count(nonempty(( [Customer].[Country].[Country],[Product].[Product].[Product])
,{[Measures].[Sales Amount],[Measures].[Internet Sales Amount]}
))
select [Measures].[rowCount]
on columns from [Adventure Works]
//2100
//Right way
with member [Measures].[rowCount]
as
count(nonempty(
filter(([Customer].[Country].[Country],[Product].[Product].[Product]),[Measures].[Internet Sales Amount]>5000)
,{[Measures].[Sales Amount],[Measures].[Internet Sales Amount]}
))
select [Measures].[rowCount]
on columns from [Adventure Works]
///585
Again till i gave the RowCount measure the exact senario that I have on my row axis it fails.

Related

MDX query picking columns on different condition

As shown in the below query,
SELECT
{[Measures].[Internet Sales Amount] } ON COLUMNS
,{([Product].[City].[City].ALLMEMBERS)} ON ROWS
FROM [Adventure Works]
Where ([Promotions].[City].&[Seattle],[Geography].[State-Province].&[WA]&[US])
This will list all the Product City names in row-wise and the column sales amount. Now I have to fetch the same column based on different City and State-Provine Name. So for that, I can repeat the query like this
SELECT
{[Measures].[Internet Sales Amount] } ON COLUMNS
,{([Product].[City].[City].ALLMEMBERS)} ON ROWS
FROM [Adventure Works]
Where ([Promotions].[City].&[LA],[Geography].[State-Province].&[CA]&[US])
Now I have these two queries returning same Product City names, but Two sales amount columns based on different conditions. I want to join these results like below
SELECT
{
[Measures].[Internet Sales Amount] EXISTS ([Promotions].[City].&[Seattle],
[Geography].[State-Province].&[WA]&[US]),
[Measures].[Internet Sales Amount] EXISTS ([Promotions].[City].&[LA],
[Geography].[State-Province].&[CA]&[US])
} ON COLUMNS
,{([Product].[City].[City].ALLMEMBERS)} ON ROWS
FROM [Adventure Works];
Now, this query should produce a single result with Product City names as rows and Col1 and Col2 of Internet Sales amount based on different conditions. But the problem is, the last query is giving me an error
"Parser: The syntax for 'Exists' is incorrect."
I am new to MDX, could someone please help me on how to join these results?
I was able to solve this problem based on the solution described here!
to-join-2-mdx-queries-with-same-hierarchy

MDX - transpose rows to columns

I'm trying to display details from two rows into one using MDX. If I execute the MDX below, it returns 2 rows, one containing the 998 Key and one containing the 999 Key
SELECT NON EMPTY {
[Measures].[FactTableCount] } ON COLUMNS,
NON EMPTY { ([DimXXXX].[XXXXKey].[XXXXKey].ALLMEMBERS
* ([DimAAAA].[AAAAKey].[AAAAKey],{[DimBBBB].[Key].&[998],[DimBBBB].[Key].&[999]},[DimCCCC].[CCCCKey].[CCCCKey])
) } ON ROWS
FROM ( SELECT ( { [DimXXXX].[XXXXKey].&[MyValue] } ) ON COLUMNS
FROM [FactTable])
It returns something like this
(columns [DimXXXX].[XXXXKey], [DimAAAA].[AAAAKey], [DimBBBB].[Key], [DimCCCC].[CCCCKey], [Measures].[FactTableCount])
MyValue, MyAAAAKey1, 998, MyCCCCKey1, 1
MyValue, MyAAAAKey2, 999, MyCCCCKey2, 1
However I want to return one row like this
`(columns [DimXXXX].[Key], [DimAAAA].[AAAAKey], [DimAAAA].[AAAAKey], [DimBBBB].[Key], [DimBBBB].[Key], [DimCCCC].[CCCCKey], [DimCCCC].[CCCCKey], [Measures].[FactTableCount])
MyValue, MyAAAAKey1, MyAAAAKey2, 998, 999, MyCCCCKey1, MyCCCCKey2, 1
Among other things (such as using SETs, putting the 998/999 logic after the ROWS/COLUMNS, etc) I've tried
SELECT NON EMPTY {
[Measures].[FactTableCount] } ON COLUMNS,
NON EMPTY { ([DimXXXX].[XXXXKey].[XXXXKey].ALLMEMBERS
* ([DimAAAA].[AAAAKey].[Key],[DimBBBB].[Key].&[998],[DimCCCC].[CCCCKey].[CCCCKey])
* ([DimAAAA].[AAAAKey].[Key],[DimBBBB].[Key].&[999],[DimCCCC].[CCCCKey].[CCCCKey])
) } ON ROWS
FROM ( SELECT ( { [DimXXXX].[XXXXKey].&[MyValue] } ) ON COLUMNS
FROM [FactTable])
...however because the AAAAKey hierarchy is repeated I receive the error message "The AAAAKey hierarchy is used more than once in the Crossjoin function"
Is there a way to do do this ?
Based on your comment below I have a sample.Let me know if it works.
I think I can see what you're saying however the measures are one
thing, but the dimension values are another - say Record1:MyValue,
MyAAAAKey1, 998, MyCCCCKey1, 2 and Record2: MyValue, MyAAAAKey2, 999,
MyCCCCKey2, 5 - I would like to output MyValue, MyAAAAKey1,
MyAAAAKey2, 998, 999, MyCCCCKey1, MyCCCCKey2, 2, 5
So in the query below I am trying to simulate your problem.
select
{[Measures].[Internet Sales Amount]}
on columns,
non empty
([Customer].[City].[City],{[Product].[Category].&[1],[Product].[Category].&[3]},[Product].[Subcategory].[Subcategory])
on rows
from [Adventure Works]
Result
Now onw way is to take the changing values to columns, "{[Product].[Category].&1,[Product].[Category].&2}" in my case and "{[DimBBBB].[Key].&[998],[DimBBBB].[Key].&[999]}" in your case
select
{
({[Product].[Category].&[1],[Product].[Category].&[3]},[Measures].[Internet Sales Amount]),
([Product].[Category].defaultmember,[Measures].[Internet Order Quantity])
}
on columns,
non empty
([Customer].[City].[City],[Product].[Subcategory].[Subcategory])
on rows
from [Adventure Works]
Result:
Note how the values are only repeated for the relevent column. This does add an extra column but you rows are now half the orignal count.
Edit: to handle the requirement based on the comment
1st row of the grid would be Ballard, Bikes, Mountain Bikes, Road
Bikes. The 2nd: Ballard, Clothing, Caps, Gloves. The 3rd: Barstow,
Bikes, Road Bikes, null. I want to merge/list the actual dimension
values
So to achieve above we have two options. But in either case some manipulation on UI would be required.
1)First option
with member
measures.t
as (nonempty(existing([Customer].[City].currentmember,[Product].[Category].currentmember,[Product].[Subcategory].[Subcategory].members),[Measures].[Internet Sales Amount])).item(0).item(2).name
member measures.t1
as (nonempty(existing([Customer].[City].currentmember,[Product].[Category].currentmember,[Product].[Subcategory].[Subcategory].members),[Measures].[Internet Sales Amount])).item(1).item(2).name
select
{measures.t,measures.t1}
on columns,
nonempty(([Customer].[City].[City],{[Product].[Category].&[1],[Product].[Category].&[3]}),[Measures].[Internet Sales Amount])
on rows
from [Adventure Works]
2)The second option,
with member
measures.t1
as
[Customer].[City].currentmember.name
member measures.t2
as
[Product].[Category].currentmember.name
member measures.t3
as (nonempty(existing([Customer].[City].currentmember,[Product].[Category].currentmember,[Product].[Subcategory].[Subcategory].members),[Measures].[Internet Sales Amount])).item(0).item(2).name
member measures.t4
as (nonempty(existing([Customer].[City].currentmember,[Product].[Category].currentmember,[Product].[Subcategory].[Subcategory].members),[Measures].[Internet Sales Amount])).item(1).item(2).name
select
{measures.t1,measures.t2,measures.t3,measures.t4}
on columns,
nonempty(([Customer].[City].[City],{[Product].[Category].&[1],[Product].[Category].&[3]}),[Measures].[Internet Sales Amount])
on rows
from [Adventure Works]

MDX Query - Select Columns From Same Dimensions

I have a requirement displaying data from same dimension in more than 1 column. For eg. I want to show data Year and Month wise. In my dimension structure, Year and Month belongs to same hierarchy. When I run below query I get error. PFB the query.
Select NON EMPTY {[Measures].[Target Actual Value]} ON 0,
NON EMPTY {[Realization Date].[Hierarchy].[Year Name].Members *
[Realization Date].[Hierarchy].[Month Year]} ON 1
From [Cube_BCG_OLAP]
The error I get is Query (2, 12) The Hierarchy hierarchy is used more than once in the Crossjoin function. I am new to MDX queries. Please help in this regard. Thanks in advance.
Select NON EMPTY {[Measures].[Target Actual Value]} ON 0,
NON EMPTY {[Realization Date].[Hierarchy].[Year Name].Members ,
[Realization Date].[Hierarchy].[Month Year]} ON 1
From [Cube_BCG_OLAP]
Instead of CROSSJOIN have a set as above. In a set, you can put members from same hierarchy
I like Sourav's answer - but it will put the results in one column which is slightly different than the question.
In AdvWorks this is in one column:
SELECT
[State-Province].MEMBERS ON COLUMNS
,{
[Date].[Calendar].[Calendar Year].MEMBERS
,[Date].[Calendar].[Month].MEMBERS
} ON ROWS
FROM [Adventure Works];
It is possible to switch to two columns and use a cross join but you need to find out the details of your Date dimensions Attribute hierarchies (as opposed to User hierarchies):
SELECT
[State-Province].MEMBERS ON COLUMNS
,
[Calendar Year].[All Periods].Children
* [Month].MEMBERS ON ROWS
FROM [Adventure Works];
In your cube maybe something like this:
SELECT
NON EMPTY
{[Measures].[Target Actual Value]} ON 0
,NON EMPTY
[Year Name].MEMBERS
*
[Month Year].MEMBERS ON 1
FROM [Cube_BCG_OLAP];

Select kpi with month on columns

I want to get two plant's oee per month in a specific year (2013), probably it's pretty trivial but I don't know how to do it:
with member [Measures].[OEE] as 'OEE'
select
{
[Equipment].[Plant Hierarchy].[Group].[DEMO_PLANT],
[Equipment].[Plant Hierarchy].[Group].[DEMO_PLANT2]
} on columns,
{
[Time].[Month]
} on rows
from ExpertPlan
where [Time].[Year].&[2013-01-01T00:00:00]
the select is ok (plants on columns and months on rows), but i'm not sure about the "with" usage to get the values be the [Measures].[OEE]
With is for custom calculated members and custom sets.
Add your measure to the slicer (WHERE clause)
SELECT
{
[Equipment].[Plant Hierarchy].[Group].[DEMO_PLANT]
,[Equipment].[Plant Hierarchy].[Group].[DEMO_PLANT2]
} ON COLUMNS
,{[Time].[Month]} ON ROWS
FROM ExpertPlan
WHERE
(
[Time].[Year].&[2013-01-01T00:00:00]
,[Measures].[OEE]
);
Here are a couple of prototyped ways of approaching this in AdvWrks cube:
SELECT
[Customer].[Country].&[United States] ON COLUMNS
,[Date].[Calendar].[Month] ON ROWS
FROM [Adventure Works]
WHERE
(
[Date].[Calendar Year].&[2007]
,[Measures].[Internet Sales Amount]
);
SELECT
[Customer].[Country].&[United States] ON COLUMNS
,Descendants
(
[Date].[Calendar].[Calendar Year].&[2007]
,[Date].[Calendar].[Month]
) ON ROWS
FROM [Adventure Works]
WHERE
[Measures].[Internet Sales Amount];
Both of the above result in this result cell set:
Adding on to the other answer, you can also employ a subselect.
SELECT
{
[Equipment].[Plant Hierarchy].[Group].[DEMO_PLANT]
,[Equipment].[Plant Hierarchy].[Group].[DEMO_PLANT2]
} ON COLUMNS
,{[Time].[Month]} ON ROWS
FROM
(
SELECT [Time].[Year].&[2013-01-01T00:00:00] ON 0
FROM [ExpertPlan]
)
WHERE
{[Measures].[OEE]}
In MDX, WHERE is the 3rd axis, although it is not too apparent. Think it to be like excel, where you have the rows, columns and values. You can put the hierarchies(attribute) on any of the axes([Measures] also behaves like any regular hierarchy). It will just change the way your final output will look like.

Change Dates to numbers

This is the script:
SELECT
{[Measures].[Internet Order Count]} ON COLUMNS
,Descendants
(
[Date].[Calendar].[Month].[August 2006]
,[Date].[Calendar].[Date]
,self
) ON ROWS
FROM [Adventure Works];
It returns this:
Can I change the script so that instead of dates it returns integers starting at either 0 or 1 i.e. the first would be 1 the second would be 2 etc.
This adds a counter but I'd like to get rid of the date column:
WITH
MEMBER [Measures].[r] AS
Rank
(
[Date].[Calendar].CurrentMember
,[Date].[Calendar].[Month].[August 2006].Children
)
SELECT
{
[Measures].[r]
,[Measures].[Internet Order Count]
} ON COLUMNS
,[Date].[Calendar].[Month].[August 2006].Children ON ROWS
FROM [Adventure Works];
This will be difficult, as what you have on the rows and columns are sets of tuples of members, either physical or calculated ones.
What you could do of course is this:
WITH Member [Date].[Calendar].[1] AS [Date].[Calendar].[Date].&[20060801]
Member [Date].[Calendar].[2] AS [Date].[Calendar].[Date].&[20060802]
...
Member [Date].[Calendar].[31] AS [Date].[Calendar].[Date].&[20060831]
SELECT
{
[Measures].[Internet Order Count]
} ON COLUMNS
,
{
[Date].[Calendar].[1],
[Date].[Calendar].[2],
...
[Date].[Calendar].[31]
}
ON ROWS
FROM [Adventure Works]
This may be feasible in case you generate the query with a tool.
However, in cases like this, I normally would keep the query like your second query, and just ignore the row headers in the client tool.