Rank Functions in MDX

I know its looks weird to ask for Rank function”s” in MDX because there is only one for it.
But in SQL we have multiple Rank functions and used under different circumstances for solving different purposes. Those are RANK, ROW_NUMBER, NTILE and DENSE_RANK.

If SQL has it why not in MDX!!!! So I tried to give you few examples so that you can call the functionality of Rank functions of SQL in MDX. I saw few post online but those were so bloody complex that it took time for me to understand what they were trying to do, and yet not much useful.

Below is the Query with different calculated measures and then the screenshot from the result. Calculated measure names are actually based on T+SQL ranking functionality:


WITH

MEMBER [MEASURES].[SEM_COUNT] AS
COUNT(NONEMPTY([Date].[Calendar].[Calendar Semester].MEMBERS
,[Measures].[Order Count]) )
--This measure gives me repeating values and I needed same in
--showing example Rank

MEMBER [ROW_NUMBER] AS
RANK(([Product].[Category].CURRENTMEMBER
,[Product].[Subcategory].CURRENTMEMBER) ,
[Product].[Category].[Category]
*[Product].[Subcategory].[Subcategory]
)
-- Identity column for all the rows in result set

MEMBER [ROW_NUMBER_ORDER] AS
RANK([Product].[Category].CURRENTMEMBER,
ORDER([Product].[Category].[Category],[Measures].[Order Count], ASC))
-- To Replace ORDER BY of ROW_NUMBER in SQL by using MDX ORDER
-- it works same as expected, ranking of rows are done based on measure

MEMBER [ROW_NUMBER_PARITION] AS
RANK(([Product].[Category].CURRENTMEMBER,
[Product].[Subcategory].CURRENTMEMBER) ,
[Product].[Category].CURRENTMEMBER
*[Product].[Subcategory].[Subcategory]
)
-- To have a functionality of PARTITION BY in SQL, i built this example
-- where Ranks/ Row Numbers are given based on Category and Subcategory
-- it is not same as identity column as given above

MEMBER [RANK_DENSE] AS
RANK([Product].[Category].CURRENTMEMBER,
[Product].[Category].[Category]
)
-- It’s actually Dense Rank of SQL that we have RANK in MDX
-- Here we don’t do any manipulation and look we have a Dense rank for
-- for Categories
-- Important to Note is that Categories ranks are coming like 1,1,1,1 then 2,2,2,2
-- Not like 1,1,1,1 and 5,5,5,5

MEMBER [RANK] AS
RANK(([Product].[Category].CURRENTMEMBER,
[Product].[Subcategory].CURRENTMEMBER) ,
[Product].[Category].CURRENTMEMBER
*[Product].[Subcategory].[Subcategory]
, [MEASURES].[SEM_COUNT]
)
-- This is example for RANK in SQL
-- Important to Note is that if the measure value
-- are same for multiple rows then values will be like 1,1,1 then 4,4,6 . . .
-- which is expected from RANK function on SQL but here it is a bit complex
-- To get this we have to use Current Member and Measure in Rank properly

SELECT {[ROW_NUMBER],
[ROW_NUMBER_PARITION],
[ROW_NUMBER_ORDER],
[RANK_DENSE],
[RANK],
[MEASURES].[SEM_COUNT],
[Measures].[Order Count]} ON 0,

-- ORDER function below doesn’t impact anything for RANK measures.
ORDER ({[Product].[Category].[Category]}
* {[Product].[Subcategory].[Subcategory]}
, [Measures].[Order Count])

ON 1
FROM [Adventure Works]
-- Below filter I used to validate few points in Ranks of result set. You can
-- of course avoid.
WHERE [Date].[Calendar].[Calendar Semester].&[2008]&[2]

Result (click on image to enlarge)
Result: Rank Funcitons in MDX

So you can study the MDX and result from the post. Here I can explain in detail what I did in MDX for different cases but I believe these example are simplest I can come up with and can be understood easily. Still in case of any doubt or explanation needed please comment and I’ll be ready to help.

These example doesn’t have NTILE but I’ll try to get some time and add alternative for it later.

Advertisements

Posted on April 24, 2014, in Begin BI, MDX, SSRS Reporting and tagged , , , , , , , , , , , , , , . Bookmark the permalink. 4 Comments.

  1. Awesome compilation of thoughts; I have idea to add create NTILE function.

    NTILE(x) function accepts one argument and bucketize all the rows in x parts; We can achieve it by using quotient function on COUNT(*) and Row Number like:
    NTILE(x) = INT(ROWNUMBER / INT(COUNT / X)) + 1
    I have not test it out, will post it again with some sample data

  2. Very good Explanation ..Keep going

  3. You know this is the same in any other field.
    You would think past showes us at least anything, but no.
    Feel free to disagree but the world is changing, and none of us have no control over it.
    E.g., If only Obama had any balls to put Putin to his place, but it seems like it’s never happening, welcome WW3.
    Awesome post, thanks!
    Sarah http://phyto-renew350i.com/

  4. Steven Neumersky

    I think Chris Webb or Rob Collie blogged about NTILE in MDX at one point, but I cannot remember.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: