Power Pivot: Average by group using many-to-many table relationship - excel

I have three tables in Power Pivot. Pupils, Baselines and Reports. The Pupils table connects to the Reports and Baselines tables via a One to Many relationship as shown below.
The Reports table has each pupil listed multiple times for each subject they have a report in. They are also listed multiple times in the Baselines table for each baseline score they have. What I want to accomplish is to create a measure that calculates the average baseline score in each subject. So take all pupils who have a maths report, I want to know the average baseline score in maths.
I tried the following measure:
Av Baseline:=AVERAGEX( CALCULATETABLE( Baselines, Baselines[Type] = "Overall" ), Baselines[Average] )
However the above when used in a pivot table produces the same result for all subjects, so the filter context is not being applied. I keep hearing people using bridge tables, which does add a ton of data and are not very efficient so I hope to avoid those if at all possible.
I have provided some example data with the desired output table, hope that helps?

Could you please test this:
Note: I hope Your Pupils table has a column called [Subject Code] It is not clear from your shared data.
Version - 1
Av Baseline :=
AVERAGEX (
VALUES ( Pupils[Subject Code] ),
CALCULATE (
SUM ( Baselines[Average] ),
CALCULATETABLE ( Baselines, Baselines[Type] = "Overall" )
)
)
Version - 2
Av Baseline =
VAR Combin =
SUMMARIZE (
Baselines,
Baselines[Type],
Pupils[Subject Code],
Baselines[Result]
)
VAR Combinfiltered =
FILTER ( Combin, Baselines[Type] = "Overall" )
VAR Result =
CALCULATE ( AVERAGE ( Baselines[Result] ), Combinfiltered )
RETURN
Result

Related

DAX Power Pivot Building a Cash Flow Statement (indirect method)

Here is the current file for this question (download from OneDrive)
I have the following data model:
This is the sample data in each table:
I have this DAX measure to calculate the running sum and get the subtotals for the income statement:
IF (
HASONEVALUE ( DIM_IncStatement[Label] );
CALCULATE (
[Total Value];
ALL ( DIM_IncStatement );
DIM_IncStatement[Code] < VALUES ( DIM_IncStatement[Code] )
)
)
And this one for the operational profit:
=
CALCULATE (
[Subtotal Income Statement];
ALL ( DIM_IncStatement[Level1] );
FILTER ( DIM_IncStatement; DIM_IncStatement[Code] = 9 )
)
Currently the pivot table for the income statement looks like this:
As the cash flow statement if built upon some information from the income statement, I need to get the information and put it in the corresponding rows.
This is the basic structure of the cash flow statement:
QUESTION:
What's the DAX measure to get the "Operational profit", "Cost depreciation", "Expense depreciation", and finally the EBITDA (which is the sum of the previous) in place in the cash flow report?
I'have tried this for the operational profit, but after adding the measure, then pivot table gets empty:
=
CALCULATE (
[Operational profit];
ALL ( DIM_Cash_Flow );
FILTER ( DIM_Cash_Flow; DIM_Cash_Flow[Report code] = "OP" )
)
If anybody can give a hint, I'd really appreciate it...being trying for hours!

Calculating Variance and Variance% in Dax

In my PBIX File, I have measures that calculate Revenue, COGS, Gross Margin etc.
Revenue = Sum(Amt)
More measures that calculate value for Last year Revenue_LY, COGS_LY and GM_LY.
Revenue_LY = CALCULATE (
[Revenue],
FILTER (
ALL ( 'Date' ),
'Date'[FinYear]= MAX ( 'Date'[FinYear] ) - 1 && 'Date'[FinPeriod] = max('Date'[FinPeriod])
)
)
Now I need variance and variance% measures for each which compare data against last year and budget. The amount of measures is just getting too many.
Revenue_CY-LY = CALCULATE([Revenue],KEEPFILTERS(Versions[VersionCode] = "Act")) - CALCULATE([Revenue_LY],KEEPFILTERS(Versions[VersionCode] = "Act"))
Revenue_CY-LY% = IF([Revenue_CY-LY] < 0, -1, 1) *
IF(
ABS(DIVIDE([Revenue_CY-LY],[Revenue])) > 99.9,
"n/a",
ABS(DIVIDE([Revenue_CY-LY],[Revenue])*100)
)
Is there a way to summarize the measures used. I don't want to create individual measures of each variance.
Yes. You can create a dynamic measure.
First create Revenue, COGS, Gross Margin, etc. measures.
Revenue = SUM([Amt])
COGS = SUM([Cost])
Gross Margin = [Revenue] - [COGS]
...
Then you create a table with one row for each of your measures:
My Measures = DATATABLE("My Measure", STRING, {{"Revenue"}, {"COGS"}, {"Gross Margin"}})
The names don't need to align with your actual measures, but they will be displayed so make them presentable.
Then you create a measure on that table which will dynamically be the same as the selected row in the table:
Selected Measure = SWITCH(SELECTEDVALUE('My Measures'[My Measure], BLANK()), "Revenue", [Revenue], "COGS", [COGS], "Gross Margin", [Gross Margin], BLANK())
Next you go and create all the complicated time-intelligence measures using the [Selected Measure] as the base:
Dynamic_LY = CALCULATE (
[Selected Measure],
FILTER (
ALL ( 'Date' ),
'Date'[FinYear]= MAX ( 'Date'[FinYear] ) - 1 && 'Date'[FinPeriod] = max('Date'[FinPeriod])
)
)
And then you can do [Dynamic_CY-LY] and [Dynamic_CY-LY %] in a similar manner to the ones in your question, replacing references to the [Revenue] measure with references to the dynamic measures.
Now you can either use a slicer on the 'My Measures'[My Measure] column to dynamically change every instance of [Dynamic_CY-LY] and the other dynamic measures, or you can add a filter on each visualisation to filter 'My Measures'[My Measure].
It might be that you'd also like to have a default value for [Selected Measure] instead of defaulting to BLANK(); just put that in last position in the SWITCH() function.

Power Pivot "dynamic" joins

I have a situation where I kind of need a many-to-many join - which I know isn't possible.
I have one fact table and two dimension tables.
The fact table contains account numbers (as in GL accounts) and amounts. Plus a date field, so the account numbers are not unique.
The first dimension table has just one column listing the reports that can be created by combining the accounts in different ways.
The second dimension table could be called a "roll-up" table. It has 3 columns: report, account, and a line item description field. The latter defines which line on the respective report that the account should be mapped to.
So I want to have a pivot table that has the line item description in the row area and the amount in the values area. With a mechanism for the user to specify which report they want to view. But the join on the account field between the roll-up table and the fact table is many-to-many. If the roll-up table were somehow filtered based on the specific report that the user has selected, THEN it would become one-to-many. Hence the "dynamic" joins in my title.
I've been trying to come up with a connecting table of some kind, but without any luck so far. If anybody has any suggestions/pointers, that would be much appreciated.
I figured out a way to do it using a DAX formula that calculates the field to be placed in the Values area. It uses FILTER and CROSSJOIN combinations to effect the dynamic joins. Note that in order to use a CROSSJOIN I added prefix letters to a couple of the field names (to make them unique). Also, I made it that the Report table (the first dimension table I described) has only one row - containing the report that the user wishes to view.
The DAX formula is as follows:
SUMX (
FILTER (
CROSSJOIN (
fBalances,
FILTER (
CROSSJOIN (
dRollUp,
dReport
), dRollup[Report] = dReport[uReport]
)
), fBalances[fAccount] = dRollUp[Account]
), fBalances[Amount]
)
Subsequent update: I moved it into Power BI where I added a parameter (called myReport) for the user to specify the report. Consequently I deleted the dReport table.
So the Power BI DAX formula becomes:
SUMX (
FILTER (
CROSSJOIN (
fBalances,
FILTER (
CROSSJOIN (
dRollUp,
myReport
), dRollup[Report] = FIRSTNONBLANK ( myReport[myReport], TRUE() )
)
), fBalances[fAccount] = dRollUp[Account]
), fBalances[Amount]
)

relationship filter in powerBI or powerpivot

i am using the powerBI tools (powerpivot) to create a data model. i am done the model. the model include the product, customer dimensions and sales fact table. i have made the relationship and hierarchy in the model. now i have a requirement to show the total revenue of all the customer who brought product 1,2,3.
for example customer A brought product 1 and product 5 and the total revenue from this customer is 50 so i want to show 50 as a result
customer B bought product 4 and i do not want to include this customer in my output.
i can do the same in microstratergy using relationship filter but how can i do the same in powerpivot or powerview or powerBI.
Please help
Thanks in Advance
In PowerPivot, relate Sales table with Customer table (Lookup table) and Relate Sales table to Product table (Lookup table).
Create following two measures
[HasPurchased X Products] =
OR (
OR (
CONTAINS ( Sales, Sales[ProductID], 1 ),
CONTAINS ( Sales, Sales[ProductID], 3 )
),
CONTAINS ( Sales, Sales[ProductID], 5 )
)
[DesiredMeasure] =
IF (
Sales[HasPurchased X Products] = TRUE (),
SUM ( [Amount] ),
BLANK ()
)
Select Customers in ROWS and add [DesiredMeasure] in VALUES, pivot table will show desired result.
Additionally to what Abhijeet said, which is a nice robust solution, you might also just filter the chart in Power View. Assuming you have a relationship between sales and products table, you can select the chart in Power View, open the Filters pane, select per chart filters, add Product to the chart filters and filter to include only productions 1,2,3. This will automatically calculate the measure. Now Abhijeet's solution is better if you need that calculation to be reused. This solution works great if you're in a 'what if' scenario where you'd like to say "what are the sales for products 1,2,3" and in another breath say "actually i'm interested in sales for products 2,3 only, so me that instead.".
HTH,
-Lukasz
http://dev.powerbi.com
http://blogs.msdn.com/powerbidev

DAX / PowerPivot cross-join type of query spread to unsummarize/de-aggregate data

So, I have an extension to the question I asked here a while ago (ref: DAX / PowerPivot query functions to spread aggregated values over time period ), which I’ve been beating my head against the wall on.
I’ve got the same general data (the output of a MS Project export) that has tasks, durations, assignments, etc. Tasks have been categorized against which project/application they relate to & I’m able to do that spread of hours over time without issue. Where the problem lies is in spreading values from a custom field across all others.
Example output from the existing pivot:
What I’m trying to get to is having everything from “ALL” spread the hours evenly across all of the other Related_Applications - there are about 20, and there is a table for them, so I would use a COUNTROWS().
Using the above as the example, what I’m trying to get to is having it so that the hours (and Name) for each of the ALL show up in each of the Related_Applications. E.g. Information Assurance and Security in Month 2 of 2015 should be spread by hours / countrows(all(related_applications)). Similarly, if you were to use the Systems Administrator values, they’d need spread & added to the existing row value. The target output of the DAX would be something like a CrossJoin and end up like this:
I keep thinking I’m close, and added a dummy table for “SpreadValuesSheet” to use the ALLEXCEPT and ALL functions. It contains the values that should spread (currently have 3x … ALL, PM and CM). I have another table for “ApplicationsSheet” that has the 30x or so apps that the hours there should spread to.
The data model # current is set up like so:
I can get the pieces individually; but can’t seem to get the measure back into the AssignmentsSheet to work (so I can have the time spread, filters by resources, etc.) … I managed that with the definitions of the calculated columns and measures below:
AssignmentsSheet:
MeasureSumScheduledWork:=sum([Scheduled_Work])
Hours Apportioned Raw:=DIVIDE (
CALCULATE (
[MeasureSumScheduledWork],
FILTER (
AssignmentsSheet,
AssignmentsSheet[Start_Date] <= MAX ( DateSheet[Date] )
&& AssignmentsSheet[Finish_Date] >= MAX ( DateSheet[Date] )
)
)
, ( COUNTROWS(DATESBETWEEN ( DateSheet[Date], FIRSTDATE ( AssignmentsSheet[Start_Date] ), LASTDATE ( AssignmentsSheet[Finish_Date] ))))
)
SpreadHoursMeasure:=SUMX (
VALUES ( DateSheet[Date] ),
SUMX ( VALUES ( AssignmentsSheet[Index] ), [Hours Apportioned RAW] )
)
Which works perfectly. Trying to spread out the others, I start running into issues. I currently am stuck with the following measures:
UFSpreadHoursMeasure:=CALCULATE(
SUMX (
VALUES ( DateSheet[Date] ),
SUMX( VALUES ( AssignmentsSheet[Index]), [Hours Apportioned Raw])
), RELATEDTABLE(SpreadValuesSheet))
SpreadAllValuesMeasure:=[SpreadHoursMeasure]+CALCULATE([UFSpreadHoursMeasure],all(ApplicationsSheet))
SpreadValuesSheet:
Calculated Column:
SumHours =[SpreadHoursMeasure]
MeasureSpreadHours:=sum([SumHours])
ApplicationsSheet
Calculated Columns:
SumHours=[SpreadHoursMeasure]
SpreadHours=[MeasureSpreadHours]/COUNTROWS(ApplicationsSheet)
TotalHours==[SumHours]+[SpreadHours]
MeasureSpreadSumTotalHours:=sum([TotalHours])

Resources