Join us at FabCon Atlanta from March 16 - 20, 2026, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.
Register now!The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now! Learn more
Hello,
I'm trying to calculate a "price evolution" calculation with a calculated column, so that for each project we calculate the difference between the first period (price 1) and its last period (where a value is available). My table looks like the following, and the last column is the expected outcome:
- For project a, price 1 - price 2, divided by 2 (since there's only 2 year columns containing a 'price' value for this project), and then divided by price 1 column. Please advise.
| project | price1 | price2 | price3 | price4 | price erosion (percentage) |
| a | 2 | 5 | -0.75 | ||
| b | 3 | 4 | 5 | -0.22 | |
| c | 6 | 7 | 9 | 3 | 0.125 |
Thank you.
Solved! Go to Solution.
Hi @tomekm
Try the following:
Price erosion =
-- Capture the value from the 'price1' column of the table.
VAR _price1 = tbl[price1]
-- Create a filtered table '_tbl' using SELECTCOLUMNS, assigning indices (1, 2, 3, 4) to prices.
-- The SELECTCOLUMNS function assigns column names ("Index" and "Price") to the two columns.
-- Then, the FILTER function removes any rows where 'Price' is blank.
VAR _tbl =
FILTER (
SELECTCOLUMNS (
{
( 1, tbl[price1] ), -- Assign 1 to 'price1'
( 2, tbl[price2] ), -- Assign 2 to 'price2'
( 3, tbl[price3] ), -- Assign 3 to 'price3'
( 4, tbl[price4] ) -- Assign 4 to 'price4'
},
"Index", [Value1], -- 'Index' column represents the position of each price
"Price", [Value2] -- 'Price' column represents the actual price values
),
NOT ( ISBLANK ( [Price] ) ) -- Filter out rows where 'Price' is blank
)
-- Combine the non-blank prices into a string separated by "|" using CONCATENATEX,
-- and sort the prices by 'Index' (ascending order).
VAR _concat =
CONCATENATEX ( _tbl, [Price], "|", [Index], ASC )
-- Calculate the length of the concatenated string (number of price values).
VAR _len =
PATHLENGTH ( _concat )
-- Extract the latest (last) price from the concatenated string.
VAR _latestprice =
PATHITEM ( _concat, _len, 1 )
-- Calculate the difference between the first price (_price1) and the latest price (_latestprice).
VAR _diff = _price1 - _latestprice
-- Return the price erosion calculation as the difference divided by the length of the prices,
-- and then divide by the initial price (_price1) to normalize the value.
RETURN
DIVIDE ( DIVIDE ( _diff, _len ), _price1 )
Note: Index in the _tbl variable is important as CONCATENATEX combines values by ascending order if no order column is specified.
Hi @tomekm
Try the following:
Price erosion =
-- Capture the value from the 'price1' column of the table.
VAR _price1 = tbl[price1]
-- Create a filtered table '_tbl' using SELECTCOLUMNS, assigning indices (1, 2, 3, 4) to prices.
-- The SELECTCOLUMNS function assigns column names ("Index" and "Price") to the two columns.
-- Then, the FILTER function removes any rows where 'Price' is blank.
VAR _tbl =
FILTER (
SELECTCOLUMNS (
{
( 1, tbl[price1] ), -- Assign 1 to 'price1'
( 2, tbl[price2] ), -- Assign 2 to 'price2'
( 3, tbl[price3] ), -- Assign 3 to 'price3'
( 4, tbl[price4] ) -- Assign 4 to 'price4'
},
"Index", [Value1], -- 'Index' column represents the position of each price
"Price", [Value2] -- 'Price' column represents the actual price values
),
NOT ( ISBLANK ( [Price] ) ) -- Filter out rows where 'Price' is blank
)
-- Combine the non-blank prices into a string separated by "|" using CONCATENATEX,
-- and sort the prices by 'Index' (ascending order).
VAR _concat =
CONCATENATEX ( _tbl, [Price], "|", [Index], ASC )
-- Calculate the length of the concatenated string (number of price values).
VAR _len =
PATHLENGTH ( _concat )
-- Extract the latest (last) price from the concatenated string.
VAR _latestprice =
PATHITEM ( _concat, _len, 1 )
-- Calculate the difference between the first price (_price1) and the latest price (_latestprice).
VAR _diff = _price1 - _latestprice
-- Return the price erosion calculation as the difference divided by the length of the prices,
-- and then divide by the initial price (_price1) to normalize the value.
RETURN
DIVIDE ( DIVIDE ( _diff, _len ), _price1 )
Note: Index in the _tbl variable is important as CONCATENATEX combines values by ascending order if no order column is specified.
It works. Thank you!
Hi,
Share some sample raw data to work with. Share data in a format that can be pasted in an MS Excel file.
you can select the first column and unpivot other columns in pq
then create a measure
Proud to be a Super User!
Thank you, but I really need to be able to accomplish this using DAX only, and not through PQ. Any ideas of how to solve this? Appreciate it.
then you can try this
Proud to be a Super User!
The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now!
| User | Count |
|---|---|
| 41 | |
| 38 | |
| 36 | |
| 30 | |
| 28 |
| User | Count |
|---|---|
| 129 | |
| 88 | |
| 79 | |
| 68 | |
| 63 |