When to use calculated field vs measure in Power BI? - powerbi

Power BI allows to add calculated field and measure to table. Both create new column and allow me to add DAX formula.
When to use calculated field vs measure in Power BI?

The most important difference is that calculated columns are calculated once when the dataset is loaded. Their value does not change later, i.e. it is not affected by slicers for example. Measures are dynamic. They are calculated whenever necessary, thus they will respond to slicers in the report.
I would recommend to read this article - Measure vs Calculated Column: The Mysterious Question? Not!

Rule of thumb: If you want to use it in a filter or a slicer, put it in a column. Otherwise, you can create it as a measure.

Link: https://learn.microsoft.com/en-gb/learn/modules/dax-power-bi-add-measures/5-compare-calculated-columns-measures
Regarding similarities between calculated columns and measures, both are:
Calculations that you can add to your data model.
Defined by using a DAX formula.
Referenced in DAX formulas by enclosing their names within square brackets.
The areas where calculated columns and measures differ include:
Purpose - Calculated columns extend a table with a new column, while measures define how to summarize model data.
Evaluation - Calculated columns are evaluated by using row context at data refresh time, while measures are evaluated by using filter context at query time.
Storage - Calculated columns (in Import storage mode tables) store a value for each row in the table, but a measure never stores values in the model.
Visual use - Calculated columns (like any column) can be used to filter, group, or summarize (as an implicit measure), whereas measures are designed to summarize.

Related

Measure inside Calculated Column; but measure depends on slicer selection

I have a tricky situation in Microsoft Power BI, and DAX language:
I am developing a new Calculated Column called Status_CC in a table called Customers; we refer to this formally as - Customers[Status_CC].
This calculated column (Customers[Status_CC]) has a number of conditions in its derivation, I am using SWITCH statement to develop it.
i.e.
Status_CC = SWITCH(
TRUE(),
.........
)
One of the conditions to develop the this Customers[Status_CC] calculated column is: Customers[HireDate] > [BonusDate].
The intersting part is, HireDate is an existing column in the Customers table.
However, [BonusDate] is a measure; this measure is developed using another table called WorkHistory.
A column (called PayCategory) from the WorkHistory table acts as a slicer in the report visual. The PayCategory column determines the value of the [BonusDate] measure.
I am using the DAX function ALLSELECTED on the slicer - the WorkHistory table's PayCategory column, to develop the [BonusDate] measure.
My question is, will the calculated column Customers[Status_CC] work correctly, if it depends on the [BonusDate] measure, which in turn depends on another table WorkHistory, which feeds PayCategory that acts as a slicer ?
I don't see any syntax error in Customers[Status_CC], but not sure whether the numbers are right.
My final report visual in Power BI Report View has:
-several columns from the Customers table, including the calculated column Customers[Status_CC]
-a slicer with PayCategory from the WorkHistory table that dictates the value of the [BonusDate] measure.
Any advice, please?
Measures used in calculated columns are calculated at model refresh time for each row. The row context is transformed to a filter context during the calculation of the measure, and is the only active filter for the measure calculation. So no report filters or slicers would be active at that point.
Note for that non-measure expressions the row context is not transformed to a filter context, so you would see a global total on each row, unless you explicitly use calculate which always changes the row context into a filter context.

Dynamic filtering based on selected value in slicer in Power BI

I am trying to create a calculated table where the data is being taken from another table and calculating the average based on the username, total average and variance between the 2 of these columns.
To create a table, I used the below DAX in Power BI which calculated the average based on the username.
scanner_speed_average_calculation =
SUMMARIZE(scanner_speed
,scanner_speed[user_name]
,"Average"
,AVERAGE(scanner_speed[order_processed]))
To calculate the group_average I used the below DAX:
group_average =
SUMMARIZE(
scanner_speed
, "Group Avg"
, average(scanner_speed[order_processed]))
And finally to calculate the variance, I used this query:
Variance = scanner_speed_average_calculation[Average] - scanner_speed_average_calculation[group_average]
Below is an outcome of these calculations.
I want to be able to make these calculations dynamic based on the selected value from the date. The table where I am taking these calculations do have the date value. I want to be able to use date range in slicer and I want these values to change based on the selected date range. I tried few things with Filter, Selectedvalue but I am not sure if I used them correctly.
Below is a main table where I took all these calculations from.
Below is a visual of where I want to group_average and variance. I want to be able to use date range and these columns should change accordingly.
Any idea or help will be appreciated. If possible then please put the entire formula. I am still a newbie in the world of DAX. Thanks in advance
power bi file
If you want a calculation to depend on a slicer, you need a Measure, not a calculated column or calculated table. Calculated columns and calculated tables are generated on refresh and physically stored in your model, so the slicers can filter them, but the slicers can't change the value of the calculations.
Measures are not persisted, but are calculated as needed based on changes to filters and slicers.
If you simply add add a measure
AverageOrdersProcessed := AVERAGE(scanner_speed[order_processed])
and put that on a visual that groups by user_name, you will get a the AVERAGE(scanner_speed[order_processed]) for each `user_name'.

In Power BI, how can I create a column that changes based on a slicer and visualization?

I'm pretty new to Power BI. I'm unsure how to approach this.
I have one visualization that displays the ten most frequently bought products in a time frame that is set by a slicer. In another visualization, I display how those products have been selling over the past few years (this time frame is not determined by the slicer). I want to display only the ten products that come from the first visualization, not the ten most common over the time frame in the second visualization.
How can I accomplish this? The approach I have in mind (and I'm open to others) is to create a true/false column that changes with the first visualization. "True" would be for products that are frequently bought as determined by the first visualization in the slicer-determined time range, and the second visualization would only look at values with a "true" in that column. How can I create a column (or table, maybe?) that changes depending on a visualization?
Clarification: most of the pages will say Top10 ... Actually, the measure used was a simple Top5 that includes products with the same number of orders than the 5th product. Therefore, to avoid dealing with larger images, 7 products will be seen but it is a Top5 ranking. The idea is you can replace it with your custom TopN measure.
What I understood:
The simplification of your model plus the disconnected help table would be:
I have one visualization that displays the ten most frequently bought
products in a time frame that is set by a slicer.
The Date slicer belongs to the Dates table in the Data model.
The table viz represents the number of rows in the sales table in the
current context (for each product within the Date range).
The table viz is sorted according to the [#Rows] measure in descending
order.
The table viz only presents the TopN products even without the presence
of the [#Rows] measure due to the presence of the [TopOrders]
measure within Filters on this visual. [TopOrders] is 1.
On the second page you create:
A slicer with the Dates[Date] column (the same one used on the
previous page).
A matrix with Products[ProductName] on the rows, HDates[Year] on
the columns, and a measure on values.
From the View tab, you select the Sync Slicers option.
Inside the Sync Slicers pane:
In the Sync column, check the boxes related to the necessary pages.
In the Display column uncheck the box that contains the over
years report.
So far all we have done is pass the time frame context from page 1 to page 2.
Since the TopN context depends on the time frame context, we can now use the [TopOrders] measure as a Filters on this visual in the matrix. Again, [TopOrders] is 1.
Why do the numbers differ between rows and not between columns?
Also, in this example, the Sales table only has information up to 12/31/2020 but the visualization shows an additional year and the Sales[Amount] values for each order is $1 so that [#Orders] and [SalesAmount] are the same for easy comparison.
HDates is not related to the model and for each combination of HDates[Year]-Products[ProductName], the [SalesAmount] measure is using the information coming from the previously hidden slicer and the respective Products[ProductName] because the information coming from HDates[Year] has no effect yet.
In order to complete this exercise, it only remains to modify the [SalesAmount] measure in such a way that it removes the filter on the time frame (Dates[Date]) and it recognizes HDates[Year] as Dates[Year].
SalesAmount :=
CALCULATE(
SUM(Sales[Amount]),
ALL(Dates),
TREATAS(VALUES(HDates[Year]),Dates[Year])
)
And this is the final result.
I hope it works for someone or the idea can be improved.

Based on slicer selection create dynamic calculated table in Power BI

I’m new to Power BI. Currently facing similar issue explained below in my product development.
I have created power bi modle with below dimensions and facts from adventureworksDW.
Then I created a calculated table, which gives result as sum of sales group by ProductSubCategory and ProductCategory. Below is the DAX for the calculated table.
Now I want to create a new calculated table, which gives me TOPn ProductSubCategory based on the Total sales amount.
Below is the DAX to do this.
and model relationships looks like below.
I want this TOPn rows to be displayed based on filter condition on product category. Something like below.
This works fine when I hardcode the product category value in the DAX itself. But if I want to change this product category values from the slicer selection, then I didn’t get any results.
What you are asking for is not possible as Power BI is currently designed. Slicers cannot affect calculated tables. Calculated columns and calculated tables are evaluated once when the data is first loaded and are static until the data is refreshed.
However, you can get the table visual you want in a much simpler manner by writing the appropriate measure and putting that in the table instead of defining an entirely separate table.
TotalSales = SUM(FactInternetSales[SalesAmount])
The Top N filtering is available in the visual level filters settings.
You can simply use the SELECTEDVALUE function as shown below.
var __SelectedValue = SELECTEDVALUE('ProductSales'[EnglishProductCatogaryName])
return
Filter(
'ProductSales',
'ProductSales'[EnglishProductCatogaryName] = __SelectedValue
)
)

Is it possible to use a slicer as a parameter to a DAX Summarize function?

I have a FactLosses Table, and a DimAccumulation table. I have brought them into PowerBi and I have placed a slicer to choose which accumulation zones i am interested in.
Once the user has selected the zones, i want to perform a group by year on the losses and sum the losses into year buckets. But only on the data that applies to the zones the user picked.
I am using the following DAX code to do the group by like so...
Table = SUMMARIZECOLUMNS(FactForwardLookingAccumulation[Year], "Losses By Year", SUM(FactForwardLookingAccumulation[Net Loss Our Share Usd]))
The problem is the new table always produces the same result. i.e When i make changes to which accumulation perils should be included it makes no difference to the summation. (it is summing the entire table)
I'd like to use the slicer to filter the fact table and then have the DAX query run on the filtered list. Is this possible?
If you want these tables to be responsive to filters or slicers on your report, then you can't write these as calculated tables that show up under the Data tab since those are computed before any filtering happens.
To get what you want, you have to do everything inside of a measure, since those are what respond to slicers. If you're looking for the max loss year once the grouping and summing are completed, you can write a measure along these lines:
Year Max =
VAR CalculatedTable = SUMMARIZECOLUMNS(FactForwardLookingAccumulation[Year], "Losses By Year", SUM(FactForwardLookingAccumulation[Net Loss Our Share Usd]))
RETURN MAXX(CalculatedTable, [Losses By Year])
Writing it this way will allow the calculated table to respond to your slicers and filters.