I have a fairly complex calculated measure that works perfectly for each row of data from a cube. However, I then need a sum of those values line by line. But the behavior of calculated measures seems to be in the subtotal and total lines in Excel, it's performing the calculation again instead of summing the previous rows. Is there a way to have a calculated measure that performs it's calculation on each row, but they does a traditional SUM in the total and subtotals?
Thanks in advance.
A calculated measures does not aggregate; it will be computed each time.
There is a solution, but that is really ugly:
You would have to use something like
SCOPE([dim1].[hier1].[All]);
[Measures].[MyCalculatedMeasure] = Sum([dim1].[hier1].[bottomlevel].Members, [Measures].[MyCalculatedMeasure]);
END SCOPE;
for all hierarchies of all dimensions, be it an attribute or user hierarchy, replacing dim1, hier1, bottomlevel as appropriate.
You need to immitate real measure behavior for calculated member. Make dummy real measure with Null value and then use Scope to define your formula on the granullarity level. For more detailed answer see here: http://blog.crossjoin.co.uk/2013/05/29/aggregating-the-result-of-an-mdx-calculation-using-scoped-assignments/
I found the easiest way to do this:
Create a new named calculation in the appropriate measure table in your DSV. (Right click, add new named calculation and set its expression to be CAST(NULL as [insert appropriate data type]).
Add the new named calculation as a measure in your cube.
In the calculations area of your cube switch to script view and add the following:
({[Measures].[The named calculation you created in step 1]},Leaves())=Your complex calculation;
This sets the definition at the leaf level and all the aggregations work perfectly.
Ref: http://sqlblog.com/blogs/mosha/archive/2005/02/13/performance-of-aggregating-data-from-lower-levels-in-mdx.aspx
Related
I'll try to describe this scenario without introducing too much irrelevant info, but keeping it simple.
Using the newish Field Parameter feature in PowerBI, I created a Parameter called _Dimensions and another one called _Measures, selecting common columns in the former and common measures in the latter.
I then build a bar chart with [_Dimension Fields] for X-Axis, [_Measure Fields] for Y-axis, and a single-select slicer for each. Now when user selects a measure and a column, it draws a bar chart of their selected measure, sliced by their selected dimension.
What I'd like to do is actually make this a Pareto chart, which would entail putting in a second measure on Y-axis, but rather than having a pareto counterpart to every possible measure a user may select, I'd like to create a single measure that calculates running percent of total of [selected measure] along [selected dimension].
I was hopeful I could call the [_Dimension Fields] column that PowerBI created with its special properties from DAX, but that doesn't seem to treat them any different than any other column. I also tried NAMEOF, but that just returns a string. I was hoping it would act like INDIRECT does in Excel, treating the string as a reference, but alas.
Does the above problem statement make sense? Can anyone describe an elegant design approach to do this dynamically that does not involve just writing a version of every possible measure a user could select and then use a switch?
imagining the combo chart to look like this (pareto measure in line chart part)
edit: secondary question, but equally important to the end goal of a fully functional dynamic pareto: when user selects measure, I want the selected dimension to always be sorted desc by selected measure. This is how you do a pareto analysis, but PBI does not default to sort descending always, and each time you change the dimension (via slicer click) the chart resets sorting. Any way to ensure that the sort order is fixed correctly?
Calculation groups are the way to go and Tabular Editor is used to create these.
After much exploration, here is my solution. It's not 100% dynamic in that it requires writing custom DAX for each dimension and measure that you need to be available for dynamic use, but gets the job done for the scope of the report in question.
create field parameter from columns that I will want to dynamically use in viz: name it _Dimension
In my example, I will be using two columns from two tables: Carrier[CarrierNumber] and ShipmentLane[LaneCity]
create field parameter from measures that I will want to dynamically use in viz: name it _Measure
in my example, I have two measures I will want to be able to toggle between: Events_Late and Events_Late2. Both exist on OnTimePerformanceDetail table.
create measure to dynamically return value based on the selection of
_Measure in slicer on canvas. This seems like it should not be unnecessary with field parameter feature, but it is necessary for reasons that will be
clear if you try to do this without a custom measure.
create a pareto measure for each of the dimensions that may be
dynamically passed to viz. Each of these dynamically evaluates the base measure, but is specific to a single column for which the measure evaluates over:
create a dynamic pareto measure that chooses the correct pareto calculation based on the selection on _Dimension
create single select Slicers for _Dimension and _Measure
create combo chart, using _Dimension for X-axis, _Measure for Y-axis, and DynamicPareto for line Y-Axis. I have aliased DynamicPareto on the viz to Running% so that it shows nicely and clearly on legend
set the sort order of the chart to be ASC by Dynamic Pareto measure. This ensures that the dimension on X-axis is always sorted correctly
A few notes:
I named the dynamic pareto as "Discrete" because this only works as
designed when doing pareto on a discrete dimension, where the bars
are meant to be sorted desc by [measure]. If you are doing a
Percentile chart, which is basically the same thing, but the
dimension is sorted by dimension value instead of measure value, the
Pareto calculation needs to work slightly differently.
There are lots of Pareto measure patterns out there. I used the one
from this blog, because it's concise and performs well:
https://janizajcbi.com/2018/08/22/pareto-rule-abc-class-in-dax/
it is important that the slicers be set to single select
I discovered there is a Pareto 3rd party viz that is simple and
dynamic, but has very limited formatting features. Fine for quick
analysis, but if you have branding or formatting standards, it may
prove unusable, as in my case
in my production use case, I have a lot more dimensions and a lot
more measures that will be available. Started with just 2+2 to prove
out functionality. Just need to follow same pattern to add more
available dimensions and measures to mix.
my naming convention of * suffix is because this report is built on a
centralized data model. The * makes it easy to find measures that are
local to this report and not a base measure in the model I am
connected to.
the field parameter feature can only be used with a remote model like this if the preview feature of Use Direct Query for AAS and PBI datasets is enabled OR the field parameters are added to the base model. In my case, I'm adding the field parameters to the base model, and all of the measures here are local to the report, connected to remote model.
Looking to generate a series of dates and values on Power BI for which the first value and the increments depend on measures. (Dynamic series generation and then applying to visuals).
Tried do to this through a calculated column, however this was unsuccessful as the column is calculated before the filtering on the measure can occur - so it was providing me with undesired results.
I have also tried to use GENERATESERIES within a measure with UNION to combine the date and values series. However, I am then unable to plot this on a visual as I have multiple values for my measure.
Any help would be greatly appreciated.
Cheers
GDB007
As long as you have a fixed X-axis, you can certainly define the Y-values dynamically using measures that are dynamic.
For example:
In this example, I just defined the [StartValue] measure as a constant 1 but it could be whatever you like. The [Increment] measure here just reads in the value of a small parameter table I created to show multiple values simultaneously by dropping that column in the Legend field of the visual, but this could also be whatever you like.
Unlike Tablix, I was not able to use limiting expression such as =ceiling(rownumber(nothing)/6) in Matrix.
Do you have any ideas to achieve limiting no. of columns in matrix- in design only, without touching dataset.
Or I should create it in Tablix?
Any suggestions please?
I think the only way you could achieve this would be to specify the column and row that you want your data to appear in from within your source dataset.
This could be achieved by taking a row_number and then doing integer division (<row_number value>/6) to get the row it should fall into and then modular division (<row_number value>%6) to get the column it should fall into.
From here you can build up your tablix grouping on your row and column fields.
I have created a calculated field(Row No.), where the calculation is, Index(). Then tried to concatenate it with a field(Name) which has text data. Then I created another calculated field(Concat), where the calculation is, attr([Name])+'_'+str([Row No.]). The Concat field is showing under Measures. How can I have it as a Dimension ?
How can I create a calculated field which will make each entry in 'Name' field by adding an 'underscore' and a number to it ?
There are two possible ways to have it as a Dimension. First, the 'ATTR' is creating an aggregation, which is why it is a measure. You should be able to remove this and still concatenate with [Name]+'_'+str([Row No.]).
second, you should be able to right click on the Measure and select Convert to Discrete, then click and drag it to the Dimensions section.
You can't have a dimension based upon a call to a table calc function (such as index()), nor an aggregate function (such as sum()).
You can however convert a measure to discrete, which will allow you to use it to create headers in your view.
There is a good reason for this restriction. Dimensions are used early in the order of operations to partition data rows into blocks. They are effectively the group by clause in a SQL statement. Aggregate functions such as sum() are then applied to each partition, and table calcs are applied even later to the aggregated query results. So you can't use those results to go back in time and generate a different partition of your data rows -- which is why Tableau won't allow you to make those fields into dimensions.
Luckily, once you understand the order of operations, you can usually find other ways to get effect you need.
As a footnote, you can create a dimension based on a FIXED LOD calculated field that includes calls to an aggregate function -- such as { FIXED [Region] : CountD([Customer]) }.
In my PowerPivot I have a master data table which comes via an extract from system x. Now I want to be able to "GROUP BY" over a certain column from the same data. What would be the best approach here? There are more than 600.000 lines involved.
I have already tried following DAX query but it won't work:
SUMMARIZE('SAP extract', [cost element], sum('SAP extract'[val]))
Returns:
Query(1,, 47) Function SUMMARIZE expects a column name as argument number 3.
Kris,
I would suggest creating a new measure -- guessing from you question, that would probably be a simple SUM (see documentation here), something like:
=SUM(Sales[Amt])
This should be then automatically added to your currently active powerpivot table.
If you then want to group the data by anything, simply drag the dimension into the rows section and you should be able to see the aggregated sums sliced by the dimension you chose.
Hope this helps.