Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I define a Calculated Measure in MDX based on a Dimension Attribute?

I would like to create a calculated measure that sums up only a specific subset of records in my fact table based on a dimension attribute.

Given:

Dimension

  • Date
  • LedgerLineItem {Charge, Payment, Write-Off, Copay, Credit}

Measures

  • LedgerAmount

Relationships
* LedgerLineItem is a degenerate dimension of FactLedger

If I break down LedgerAmount by LedgerLineItem.Type I can easily see how much is charged, paid, credit, etc, but when I do not break it down by LedgerLineItem.Type I cannot easily add the credit, paid, credit, etc into a pivot table. I would like to create separate calculated measures that sum only specific type (or multiple types) of ledger facts.

An example of the desired output would be:

| Year  | Charged | Total Paid | Amount - Ledger |
| 2008  | $1000   | $600       | -$400           |
| 2009  | $2000   | $1500      | -$500           |
| Total | $3000   | $2100      | -$900           |

I have tried to create the calculated measure a couple of ways and each one works in some circumstances but not in others. Now before anyone says do this in ETL, I have already done it in ETL and it works just fine. What I am trying to do as part of learning to understand MDX better is to figure out how to duplicate what I have done in the ETL in MDX as so far I am unable to do that.

Here are two attempts I have made and the problems with them. This works only when ledger type is in the pivot table. It returns the correct amount of the ledger entries (although in this case it is identical to [amount - ledger] but when I try to remove type and just get the sum of all ledger entries it returns unknown.

CREATE MEMBER CURRENTCUBE.[Measures].[Received Payment]
AS CASE WHEN ([Ledger].[Type].currentMember = [Ledger].[Type].&[Credit]) 
OR ([Ledger].[Type].currentMember = [Ledger].[Type].&[Paid])
OR ([Ledger].[Type].currentMember = [Ledger].[Type].&[Held Money: Copay])
THEN [Measures].[Amount - ledger] 
ELSE 0
END 
, FORMAT_STRING = "Currency"
, VISIBLE = 1 
, ASSOCIATED_MEASURE_GROUP = 'Ledger'  ; 

This works only when ledger type is not in the pivot table. It always returns the total payment amount, which is incorrect when I am slicing by type as I would only expect to see the credit portion under credit, the paid portion, under paid, $0 under charge, etc.

CREATE MEMBER CURRENTCUBE.[Measures].[Received Payment]
AS sum({([Ledger].[Type].&[Credit]), ([Ledger].[Type].&[Paid])
, ([Ledger].[Type].&[Held Money: Copay])}
,  [Measures].[Amount - Ledger])
, FORMAT_STRING = "Currency"
, VISIBLE = 1 
, ASSOCIATED_MEASURE_GROUP = 'Ledger'  ;  

Is there any way to make this return the correct numbers regardless of whether Ledger.Type is included in my pivot table or not?

like image 527
Shane Delmore Avatar asked Apr 16 '10 17:04

Shane Delmore


People also ask

What is MDX calculated measure?

In Multidimensional Expressions (MDX), a measure is a named DAX expression that is resolved by calculating the expression to return a value in a Tabular Model. This innocuous definition covers an incredible amount of ground.

How do you create a calculated member?

To create a calculated member, use the New Calculated Member command on the Calculations tab of Cube Designer. You can create a calculated member within any dimension, including the measures dimension. You can also place a calculated member within a display folder in the Calculation Properties dialog box.

What is the difference between measures and a measure group?

In a cube, measures are grouped by their underlying fact tables into measure groups. Measure groups are used to associate dimensions with measures. Measure groups are also used for measures that have distinct count as their aggregation behavior.

How do you add a measure to a cube?

Assuming the cube already exists in SQL Server Data Tools, double-click the cube name in Solution Explorer to open it in Cube Designer. In the Measures pane, right-click the top node to create a new measure group, or new measures, by specifying a source table, column, and aggregation type.


2 Answers

Try EXISTING:

CREATE MEMBER CURRENTCUBE.[Measures].[Received Payment]
AS sum(Existing({([Ledger].[Type].&[Credit]), ([Ledger].[Type].&[Paid])
, ([Ledger].[Type].&[Held Money: Copay])})
,  [Measures].[Amount - Ledger])
, FORMAT_STRING = "Currency"
, VISIBLE = 1 
, ASSOCIATED_MEASURE_GROUP = 'Ledger'  ;  

Should make it pay attention to the members in play.

like image 88
Meff Avatar answered Nov 15 '22 04:11

Meff


Can't comment on Meff's answer, so I'll post my own.

You should consider using Aggregate instead of Sum, as results may not always be the ones you expect using Sum:

CREATE MEMBER CURRENTCUBE.[Measures].[Received Payment]
AS Aggregate(Existing({([Ledger].[Type].&[Credit]), ([Ledger].[Type].&[Paid])
, ([Ledger].[Type].&[Held Money: Copay])})
,  [Measures].[Amount - Ledger])
, FORMAT_STRING = "Currency"
, VISIBLE = 1 
, ASSOCIATED_MEASURE_GROUP = 'Ledger'  ; 
like image 26
mprost Avatar answered Nov 15 '22 05:11

mprost