Category Archives: SSRS Reporting

Update MDX in SSRS Auto-generated datasets

Whole objective of this post is to write better/proper/optimized MDX for SSRS Reports datasets. Small fix in our SSRS Dataset Queries in SSRS reports can optimize report as well as MDX in report. The reports which grows in complexity and data, can be really grateful for your effort on this.

Most of the times we use auto-generated MDX queries in SSRS Report datasets. But I suggest use it, with a better eye on it. It can be fixed for many better changes. I always create my own MDXs for report and if I get already created SSRS report to work on, I open dataset queries and do some tweaks to make it better.

  • 1. Remove NON EMPTY where you don’t want them.. Auto generated query keeps NON EMPTY in rows and columns of MDX, but it can cause trouble when columns get disappeared from report. Sometimes your report will fail if a measure is empty (no value) for dimensions ON COLUMNS in MDX. I would suggest remove both NON EMPTY to avoid any column getting missed due to lack of data and use NONEMPTY function to better the query.If you don’t follow me here please read about NON EMPTY in msdn to avoid report breaks in case of lesser data in cube.
  • 2. Shiny CELL PROPERTIES should be removed from auto generated MDX. You see those in the end of any dataset MDX and are meant for result viewers such as SQL Server.Sometimes these properties can be useful (mostly DIMENSION properties), when taken as members and appear in results as columns. You should delete properties which usually comes with the auto generated MDX and delete the whole section, “DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME” and “CELL PROPERTIES VALUE, BACK_COLOR, FORE_COLOR, FORMATTED_VALUE, FORMAT_STRING, FONT_NAME, FONT_SIZE, FONT_FLAGS” no use.
    Read more on properties and figure out which can be useful. Or give me a call ;).
  • 3. Use CONSTRAINED with multiple value parameters while putting them in STRTOSET like STRTOSET(@LoadPort, CONSTRAINED). Read about keyword in msdn but still; it does help query processor to understand all the values passed, belongs to same attribute hierarchy. In turn it helps query to be parsed through compiler quick. We should not avoid using it.
  • 4. Make sure of using MEMBERS in place of ALLMEMBERS. Most of the times we don’t have calculated attribute members in cube. Which means using MEMBERS is appropriate than ALLMEMBERS.
  • 5. Use MEMBERS with correct level of attribute hierarchy. Basically you should know the difference between:
    [Dim Customer].[Customer].[Customer].MEMBERS
    [Dim Customer].[Customer].MEMBERS
    This means you get additional member in second query which is actually All member of attribute hierarchy of dimension customer.
    So, if only you want this additional member use second query else first. Important note: most of the times this All member doesn’t get a Label/Name in SSRS list of members.

I can think of few more good things to do in SSRS Reporting but will share with different post. I hope I don’t forget those. Catch you in new post.

Advertisements

“Greater than” functions in MDX

Well its Sunday evening and i was about to start some work (I know its weird but this was nice work . .so . . .  ).
It’s just a feeling that mostly people say that MDX doesn’t have “Greater than” and “Smaller than” functions to use in WHERE clause. But I believe the main issue is that MDX doesn’t needs to have those. MDX is written on Cube where all the members have their unique identity (say address). “Greater than” functions works for values where you have to do a comparison. With measure values you can always use “>” operators. But if you want to do same but based on dimensional members (like date, age, may be ordered name of product etc.), you can only prepare a set of members which satisfy your need of members.
Anyways let’s talk about putting these functionality in MDX and its very simple, if you could just understand what I wrote on top.
To get “Greater than” functionality out of MDX we need to mention the set of members which falls under that range. So finally we are going to use Range function of MDX to get the requirement done.
Example here states, I want to get all the Subcategories with their Reseller Amounts after date 05/01/2008 (dates greater than 05/01/2008).


SELECT
{[Measures].[Reseller Sales Amount]} ON COLUMNS,
NON EMPTY
[Product].[Subcategory].[Subcategory]
ON ROWS
FROM
[Adventure Works]
WHERE
(
[Date].[Calendar].[Date].&[20080501]
:[Date].[Calendar].[Date].&[20080501].LASTCHILD
)

and if you want Smaller than version of it.


SELECT
{[Measures].[Reseller Sales Amount]} ON COLUMNS,
NON EMPTY
[Product].[Subcategory].[Subcategory]
ON ROWS
FROM
[Adventure Works]
WHERE
(
[Date].[Calendar].[Date].&[20080501].FIRSTCHILD
:[Date].[Calendar].[Date].&[20080501])

See the result for yourself. The same result goes with all members of Cube. You can see the result for:


SELECT
{[Measures].[Reseller Sales Amount]} ON COLUMNS,
NON EMPTY
[Product].[Subcategory].&[34].FIRSTCHILD
:[Product].[Subcategory].&[34]
ON ROWS
FROM
[Adventure Works]

To drill it more I can say it is always “Greater Than or Equals to” or “Smaller Than or Equals to”, and if you want to avoid “Equals to” part use EXCEPT function and remove it.
Mostly we have members ordered in Cube, just like DATE members and alphabetically for other dimensions. If you don’t have ordered members you will need GENERATE functions to bend those un-ordered members  to use. Best of luck and in case you have problems contact me. 🙂

Thanks a lot for reading and your thoughts, doubts, queries . . . are much appreciated in comment section.