zaterdag 9 juli 2011

SSAS/SSRS/MDX : Cascading parameters and M2M dimensions

Introduction

Well, today a post about cascading parameters in Reporting Services (SSRS) in combination with MDX coding. Cascading parameters is about defining multiple parameters in such a way that a list of values of  a parameter depends on the values of another parameter. For this post i'll build upon my lab environment as described in my earlier posts:
  • Modeling a N:M relation between dimensions (part I).
  • Building a multivalue dimension construction in SSAS ( part II).
  • Joining issue with MDXing of M2M dimension (part III).
As a matter of fact, this post could be seen as a part IV in this list because the problem is also related with the M2M dimension construction. This is explained in my former post (part III).


Scenario
What i'll describe in this post is building a cascading parameter build upon two datasets: one for department and one for location. I've seen enough examples of building parameters on SQL queries but there are not that many examples based on MDX. As decribed in the earlier posts (see above) i've the following situation:
  • Department A
    • Location 1.
    • Location 2.
  • Department B.
    • Location 2.
  • Department C.
    • Location 3.
    • Location 4.
So, the cascading parameter should show location 1 and 2 when the first parameter is department A.  Again,  when department C is chosen the other parameter should be limited to location 3 and 4.

Building the report 
First, let's setup the report in Reporting Services that returns a department, a location and a count field. I've created a datasource in SSRS, built a dataset and added the two parameters: Department and Location.


After I pressed OK and returned back to the report i noticed that there are a couple of extra (hidden) datasets created(DepartmentDepartmentDescription and LocationLocationDescription). Dataset1 is MDX query that should return data for the report.

Let's try the report and check if the cascading parameter location is depending on the department parameter. Look at the diagram below and notice that all four locations are shown, even when i choosed a different departments.


Seems that we've to add some more magic to the report. Let's look at the parameter datasets in more detail. I've copied the MDX query of the department dataset below:

WITH
MEMBER [Measures].[ParameterCaption] AS [Department].[Department Description].CURRENTMEMBER.MEMBER_CAPTION
MEMBER [Measures].[ParameterValue] AS [Department].[Department Description].CURRENTMEMBER.UNIQUENAME
MEMBER [Measures].[ParameterLevel] AS [Department].[Department Description].CURRENTMEMBER.LEVEL.ORDINAL
SELECT {[Measures].[ParameterCaption],
[Measures].[ParameterValue],
[Measures].[ParameterLevel]} ON COLUMNS ,
[Department].[Department Description].ALLMEMBERS ON ROWS FROM [MultiValueDimension]


No need for changes here. Let's take a look at the location dataset.

WITH 
MEMBER [Measures].[ParameterCaption] AS [Location].[Location Description].CURRENTMEMBER.MEMBER_CAPTION 
MEMBER [Measures].[ParameterValue] AS [Location].[Location Description].CURRENTMEMBER.UNIQUENAME 
MEMBER [Measures].[ParameterLevel] AS [Location].[Location Description].CURRENTMEMBER.LEVEL.ORDINAL 
SELECT {[Measures].[ParameterCaption], 
[Measures].[ParameterValue], 
[Measures].[ParameterLevel]} ON COLUMNS , 
[Location].[Location Description].ALLMEMBERS ON ROWS 
FROM ( SELECT ( STRTOSET(@DepartmentDepartmentDescription, CONSTRAINED) ) ON COLUMNS 
       FROM [MultiValueDimension])

The problem (as i described in my former post about the showing the right location related at the right department) is that all locations are shown because the relation between location and department isn't enforced. So i need to change the query and two important changes are needed.

First change the WITH part:

WITH 
MEMBER [Measures].[ParameterCaption] AS [Location].[Location Description].CURRENTMEMBER.MEMBER_CAPTION 
MEMBER [Measures].[ParameterValue] AS [Location].[Location Description].CURRENTMEMBER.UNIQUENAME 
MEMBER [Measures].[ParameterLevel] AS [Location].[Location Description].CURRENTMEMBER.LEVEL.ORDINAL

into:

WITH
MEMBER [Measures].[ParameterCaption] AS iif(IsEmpty([Measures].[Bridge Location Department Count]), null, [Location].[Location Description].CURRENTMEMBER.MEMBER_CAPTION)
MEMBER [Measures].[ParameterValue] AS iif(IsEmpty([Measures].[Bridge Location Department Count]), null, [Location].[Location Description].CURRENTMEMBER.UNIQUENAME)
MEMBER [Measures].[ParameterLevel] AS iif(IsEmpty([Measures].[Bridge Location Department Count]), null, [Location].[Location Description].CURRENTMEMBER.LEVEL.ORDINAL)


This part is enforcing the member to NULL when the relation is not there:

and change:

[Location].[Location Description].ALLMEMBERS ON ROWS 

into:

NONEMPTY([Location].[Location Description].ALLMEMBERS,[Measures].[Bridge Location Department Count])

This part is needed to suppress the NULLs but fon't forget to show all locations( for a specific department), even when there is no fact.This is important to notice because when i don't add this extra constraint location 4 isn't shown at Department C. This location doesn't have a factrecord stored.

And the final solution is shown below:

WITH
MEMBER [Measures].[ParameterCaption] AS iif(IsEmpty([Measures].[Bridge Location Department Count]), null, [Location].[Location Description].CURRENTMEMBER.MEMBER_CAPTION)
MEMBER [Measures].[ParameterValue] AS iif(IsEmpty([Measures].[Bridge Location Department Count]), null, [Location].[Location Description].CURRENTMEMBER.UNIQUENAME)
MEMBER [Measures].[ParameterLevel] AS iif(IsEmpty([Measures].[Bridge Location Department Count]), null, [Location].[Location Description].CURRENTMEMBER.LEVEL.ORDINAL)
SELECT {
[Measures].[ParameterCaption],
[Measures].[ParameterValue],
[Measures].[ParameterLevel]} ON COLUMNS ,
NONEMPTY([Location].[Location Description].ALLMEMBERS,[Measures].[Bridge Location Department Count]) ON ROWS
FROM (SELECT (STRTOSET(@DepartmentDepartmentDescription, CONSTRAINED) ON COLUMNS
              FROM [MultiValueDimension]))


The snippet 'FROM (SELECT (STRTOSET(@DepartmentDepartmentDescription, CONSTRAINED) ON COLUMNS FROM [MultiValueDimension]))' will change the location in a cascading parameter.

Now it's time to test this changed query. Starting up the report in preview mode is shown below (department A is showing the two locations 1 and 2):


Let's try another department (department C shows location 3 and location 4):


Conclusion
Main 'problem' is the usage of the M2M dimension (Location 2 Department) that is actually a n:m relation. To enforce the relation you have to use the second parameter of the NONEMPTY() function.

Greetz,
Hennie

7 opmerkingen:

  1. Deze reactie is verwijderd door de auteur.

    BeantwoordenVerwijderen
  2. Hi,
    This is my query : WITH
    MEMBER [Measures].[ParameterCaption] AS IIF(IsEmpty([Measures].[Country_Name_And_Code]), null, [Geography].[State_Abbr].CURRENTMEMBER.MEMBER_CAPTION)
    MEMBER [Measures].[ParameterValue] AS IIF(IsEmpty([Measures].[Country_Name_And_Code]), null,[Geography].[State_Abbr].CURRENTMEMBER.UNIQUENAME)
    MEMBER [Measures].[ParameterLevel] AS IIF(IsEmpty([Measures].[Country_Name_And_Code]), null,[Geography].[State_Abbr].CURRENTMEMBER.LEVEL.ORDINAL )

    SELECT {[Measures].[ParameterCaption],
    [Measures].[ParameterValue],
    [Measures].[ParameterLevel]} ON COLUMNS ,
    NONEMPTY([Geography].[State_Abbr].ALLMEMBERS,[Measures].[Country_Name_And_Code])
    FROM (
    SELECT ( STRTOSET(@SnapshotMPCIDetailPremiumRyearReinsuranceYear, CONSTRAINED) ) ON COLUMNS
    FROM [MPCI_Detail_Premium_Ryear]
    )

    But When I run this I get an error:
    Failed to parse the query to detect if it is MDX or DMX. (MDXQueryGenerator)

    Can you help me with this. Appreciate your help!!

    BeantwoordenVerwijderen
  3. Hey Hennie,

    Great reporting tutorials. Keep it up!
    I wanted to ask you if you find a way to pass this issue regarding multiple cascading parameters.

    https://connect.microsoft.com/SQLServer/feedback/details/268032/default-does-not-get-refreshed-for-cascading-parameters

    Cheers,
    Razvan

    BeantwoordenVerwijderen
  4. thask, what is Bridge Location Department????

    BeantwoordenVerwijderen
  5. Thanks Hennie - this was a huge help on my project!

    BeantwoordenVerwijderen
  6. @s: Although the error sounds familiar it's difficult to say what the cause is of error. I'm sorry i can't help you with this. I hope you already solved this issue by now ;-)

    @Anoniem: Bridge Location Department is a N:M relationsship between Location and department.

    @Charlotte: You're Welcome

    Greetz
    @Hennie7863

    BeantwoordenVerwijderen
  7. Hey Hannie,

    Great tutorial! Very helpful, thanks.

    As Razvan, I wonder what is your take on the default value for cascading parameters. There is a heaps of workarounds for SQL based reports but none for MDX.
    Would be great to read your thoughts about it.

    BeantwoordenVerwijderen