5
votes

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?

3

3 Answers

7
votes

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.

1
votes

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'  ; 
0
votes

I am assuming the Ledger dimention has a key within the FactLedger but the issue that it doesn't rollup right with the first MDX calculated member leads me to believe that you may want to rethink the hierachies for this.

Then a simple SUM based on your ledger type would work, does that make sense?