Query selected dimension members (tostring) - mdx

I wonder if this is possible. I want to create a calculated member that will show which dimension member is selected by a user. This member could then be used as a string to build responsive report titles (in PowerBI likely).
I've played with NAME, UNIQUENAME along with CURRENTMEMBER and such, but didn't get far, honestly I barely know where to start or if it's even possible.
For example. Say I have a country and city dimension to filter a host of measures and the user filters by "United States" and chooses a city (or three). I'd like to be able to retrieve "United States" as well as which cities were selected as a string and add it to a report title possibly to get a title like "Population stats for " city, city, city, " in ", country.

You sort of do that, take a look at how i print my slicer axis. Currentmember works when one value is used in your case you may want multiple values.
with member measures.Country
as
(existing [Customer].[Country].members).item(1).name
member measures.City
as
SetToStr(existing [Customer].[City].[City].members)
select
{[Measures].[Internet Sales Amount],measures.Country,measures.City }
on columns,
[Product].[Category].[Category]
on rows
from
[Adventure Works]
where
([Customer].[Country].&[United States],
{[Customer].[City].&[Chicago]&[IL],[Customer].[City].&[Denver]&[CO],[Customer].[City].&[Los Angeles]&[CA],[Customer].[City].&[New York]&[NY]}
)
Result

Related

MDX - Use Aggregate on a CROSSJOINed multi-dimensional set to return a grand total row

I raised a ticket on grand totals when filtering ages ago and I used the proposed solution yesterday to get one dimension working:
WITH
SET [FilteredSet] AS
{
FILTER([CDR].[CDR].Members,([CDR].[CDR].CURRENTMEMBER.MEMBERVALUE="70648") OR ([CDR].[CDR].CURRENTMEMBER.MEMBERVALUE="70646"))
}
MEMBER [CDR].[CDR].[Test] AS Aggregate([FilteredSet])
SELECT NON EMPTY {[Measures].[CS01.TenorTotal] } ON COLUMNS, NON EMPTY {[FilteredSet], [CDR].[CDR].[Test]} ON ROWS FROM [TraderCube] WHERE ([Date].[Date].[2022-04-01],[Epoch].[Epoch].[Branch].[master].[17])
(Other ticket with useful info)
MDX - Grand total missing when filtering
And as I expand the test query (to get it all working and I then expand the C# code to add it) I note that this works:
WITH
SET [FilteredSet] AS
{
FILTER(CROSSJOIN(HIERARCHIZE(DRILLDOWNLEVEL([CDR].[CDR].[ALL].[AllMember]),POST),HIERARCHIZE(DRILLDOWNLEVEL([Book].[Book].[ALL].[AllMember]),POST)),(LEFT([CDR].[CDR].CURRENTMEMBER.MEMBERVALUE,2)="66") )
}
SELECT NON EMPTY {[Measures].[CS01.TenorTotal] } ON COLUMNS, NON EMPTY {[FilteredSet]} ON ROWS FROM [TraderCube] WHERE ([Date].[Date].[2022-04-01],[Epoch].[Epoch].[Branch].[master].[17])
But we will often filter on the 2nd (or 3rd, 4th etc) dimension, like so and the total (AllMember) is filtered out from Book as it does match the INSTR comparisons.
How do I get my Aggregate MEMBER to work properly here? I've placed [?] in position as I can get this sort of setup to work on one dimension (E.g. [CDR] as shown in first code block) but here the query returns [CDR] and then the [Book] members that match and I want to 'glue' my Agregate MEMBER [?] of the measure as a grand total.
WITH
SET [FilteredSet] AS
{
FILTER(CROSSJOIN(HIERARCHIZE(DRILLDOWNLEVEL([CDR].[CDR].[ALL].[AllMember]),POST),HIERARCHIZE(DRILLDOWNLEVEL([Book].[Book].[ALL].[AllMember]),POST)),(LEFT([CDR].[CDR].CURRENTMEMBER.MEMBERVALUE,2)="66")
AND (INSTR([Book].[Book].CURRENTMEMBER.MEMBERVALUE,"72")>0 OR INSTR([Book].[Book].CURRENTMEMBER.MEMBERVALUE,"73")>0))
}
MEMBER [?] AS Aggregate([FilteredSet])
SELECT NON EMPTY {[Measures].[CS01.TenorTotal] } ON COLUMNS, NON EMPTY {[FilteredSet], [?]} ON ROWS FROM [TraderCube] WHERE ([Date].[Date].[2022-04-01],[Epoch].[Epoch].[Branch].[master].[17])
Current MDX error back is:
'The 2 objects do not have the same dimensionality: [[CDR], [Book]] and [[Measures]]'
Thanks to more advanced MDX-ers out there! :)
Leigh Tilley
TilleyTech Ltd
P.S. Sorry no screenshots...client browser trackers would detect it and I'd get in trouble!

Creating a Calculation in an Analysis cube to produce a Distinct Count by criteria

I have a multi-dimensional cube that has multiple rows for each shop. There is a ShopCount measure that is a DistinctCount over the ShopKey field in the cube, which is in another measure group. I can get Shop counts over all sorts of different dimensions, which in this case is usually location. That works fine.
Now I want a variant of this. I want an inline distinct count of shops based on another measure or dimension.
Here is an example mdx that gives me a distinct count of shops for a particular month, where the shop type is either automotive or camping.
SELECT [Measures].[Shop Count] ON COLUMNS
FROM [Retail Cube]
WHERE ([Report Date].[Month].[201905],
{[Shop].[ShopType].&[Automotive],[Shop].[ShopType].&[Camping]})
CELL PROPERTIES VALUE
In Excel, I would like to be able to get another column that has the distinct count of Automotive and Camping shops over the range of months in my database. I would like to then be able to filter the columns by all the existing dimensions that I am currently filtering by.
I tried creating a calculated field in the Calculations tab, such as:
COUNT(DISTINCT CASE WHEN [Shop].[ShopType].&[Automotive] THEN [Shop].[Shop Key]
WHEN [Shop].[ShopType].&[Camping] THEN [Shop].[Shop Key]
ELSE NULL END)
(Note: Shop Key is what I do my Distinct Count over)
After substantial processing it came up with an error in that column.
How can I achieve what I am trying to do?

Show items with no data on rows | SSAS , MDX

Working on a task that required to bring all a dimension’s data to the Pivot Table(Excel Sheet) even if they are not related to the fact.
first I was able to do it by using the option “PivotTable Options” -> “Display” -> “Show items with no data on rows” from Excel. The problem here is that using this option is going to affect the other dimensions and the requirement is to only this work for the Student dimension only and the user doesn’t like to keep changing the option back every time. then I found this solution using SCOPE, below, but just like above I could not find an away to just have the scope ignore the logic if any other dimension added so the data does not get duplicated.
SCOPE ([Program].[Program Hierarchy].MEMBERS, [Measures].[Number of Students]);
THIS = IIF(ISEMPTY([Measures].[Number of Students]), 0, ([Measures].[Number of Students]));
END SCOPE;
So is there something that I can add the SCOPE above to just work in the program dimension and get ignore/ skip and work as normal if any other dimension added to the pivot table?
Any suggestion will be appreciated.
Lets suppose that for Dimension1 ,attribute1, and the attribute "Value 1", you had nothing in Fact, so this is removed from the result, now you forced Excel to display it by selecting the option. When you add another dimension's attribute lets say Dimension2.Attribute1, since "Value 1" had nothing in Fact, therefore Cube will not understand which value of of Dimension2.Attribute1 is to be displayed in front of Dimension1.Attribute1, therefore it will display all its values. So if we have 3 values in Dimension2, attribute 1 then "Value 1" will be repeated three times. Now with Excel you cannot solve the issue, however it might just be possible to write an MDX query that works.
Edit: Query Added.
The below sample query is based on AdventureWorks, the first sample shows that the result has some nulls, if i un-comment the "non-empty" all null values will vanish, go ahead try it.
select [Measures].[Internet Sales Amount] on columns,
--non empty
[Product].[Subcategory].[Subcategory]
on rows
from
[Adventure Works]
Result without non empty
Now lets add another dimension to the query. Notice that the null value for the first row(Bib-shorts) is now repeated for all values of the second dimension, Since cube has no way to determine which value to display.
select [Measures].[Internet Sales Amount] on columns,
--non empty
([Product].[Subcategory].[Subcategory],[Date].[Calendar Quarter of Year].[Calendar Quarter of Year])
on rows
from
[Adventure Works]
Result
Now the above result shows the issue you are facing. What we now need to do is whenever there is a null value we dont need the individual members of the second dimension, rather a place holder to satisfy the tuple, will work.
In the query below I have two tuples
1) for the not null data-points. Here we display the actual member of the second dimension.
2) for the null data-points, here we use ".defaultmember" which basically means that the second dimension will behave as it was never selected. Have a close look at the second dimension it says "All Period"
select [Measures].[Internet Sales Amount] on columns,
--non empty
{filter(([Product].[Subcategory].[Subcategory],[Date].[Calendar Quarter of Year].[Calendar Quarter of Year]),[Measures].[Internet Sales Amount]>0),
filter(([Product].[Subcategory].[Subcategory],[Date].[Calendar Quarter of Year].defaultmember),[Measures].[Internet Sales Amount]=null)
}
on rows
from
[Adventure Works]
Result:

MDX calculated member dimension context

I have the following calculated member which represents the quantity of "overstocked" products:
WITH
MEMBER [Measures].[Overstocked Items Count] AS
FILTER(
[Items].[Item No].CHILDREN,
[Measures].[Overstocked Qty] > 0
).COUNT
It works just fine for any linked to the measure group dimension except for the Items dimension itself and the reasons are obvious. Is there a way to create a calculated member that would respect the context it is evaluated in? So basically if this member is evaluated against an item group code I need items count by those groups, not the entire items set.
EXISTING is a useful keyword that can add the current context to your measure:
WITH
MEMBER [Measures].[Overstocked Items Count] AS
FILTER(
EXISTING([Items].[Item No].CHILDREN),
[Measures].[Overstocked Qty] > 0
).COUNT
EXISTING is very good when you want to know the members present from a different hierarchy within the same dimension. e.g. say you have U.S.A selected from the country hierarchy (in geography dimension) and you need to count state/county members from a stateCounty hierarchy that is also part of the geography dimension then EXISTING is the correct choice.
If you want to go across dimensions so say you have U.S.A selected and you'd like to count customer, from the customer dimension who are associated with the U.S.A then I don't think EXISTING will work - you'll need to explore either EXISTS or NONEMPTY.

icCube MDX on distinct count in relation to same dimension in axis or filter

I have the following MDX statement on the $Monitoring cube:
WITH
MEMBER [Measures].[Unique Users] AS distinctcount(([User].[User].[User L].members
, [Measures].[Open Report Count])),format_string="#,#0"
SELECT
NON EMPTY { {[Measures].[Unique Users],[Measures].[Open Report Count]} } ON COLUMNS,
NON EMPTY { [Time].[Time].[Day L] } ON ROWS
FROM ( SELECT
{ lag(strtomember("[Time].[Time].["+right("0"+str(day(SchemaRefreshTime())),2) +"-"+ right("0"+str(month(SchemaRefreshTime())),2) + "-"+str(year(SchemaRefreshTime()))+ "]"), 6):strtomember("[Time].[Time].["+right("0"+str(day(SchemaRefreshTime())),2) +"-"+ right("0"+str(month(SchemaRefreshTime())),2) + "-"+str(year(SchemaRefreshTime()))+ "]") } ON 0 FROM [$Monitoring])
/*ic3navigation*/
axis 1 NON EMPTY order(nonempty(Descendants([Report].[Report], ,leaves),[Open Report Count]),[Open Report Count],desc)
FILTERBY /*ic3*/ {[Time].[Time].[ALL].&[2015].&[2015-11-27].&[27-11-2015]}
FILTERBY /*ic3*/ {[User].[User].[All Users].&[<user>]}
*) change <user> with the actual user name
*) the ...lag.. formula is used to give the last 7 days based on schema refresh time
***) this MDX query can be run on any $Monitoring cube if you have filled in an existing user
I would expect the distinctcount function to take into account the FILTERBY. So the result should be 1 (there is just one user selected). The strange thing is, that it does not. It shows more than one user, so I assume the FILTERBY on users is not taken into account for the distinctcount.
The same thing happens when I move the FILTER BY to the AXIS or to the ROWS or COLUMNS.
Is this a bug or is this something how MDX/ MDX++ works in icCube?
Please advise.
It's the expected behaviour. Welcome to advanced MDX !
A FilterBy is exactly the same as a sub-select.
Members are not filtered by a subselect or a where clause in a calculated members.
In a calculated member, a tuple that defines a hierarchy will 'overwrite' the one defined in a subquery or where clause.
------ UPDATE ------
If you want to filter the set with the where clause/subselect you've the EXISTING operator.
MEMBER [Measures].[Unique Users] AS count( Existing [User].[User].[User L].members),format_string="#,#0"
if you want only users with data for the cell tuple :
MEMBER [Measures].[Unique Users] AS count( nonempty( Existing [User].[User].[User L].members, [Measures].[Open Report Count])),format_string="#,#0"
If you've a large number of users I'd advise adding a measure [Distinct Users] that is a distinct count on the user id. This way you avoid all complexity that we're facing here.