how to compute the growth rate in Power Bi using Dax? - dax

I want to have a column in power bi showing the growth rate of sales. I have a table like
year
count
1395
123
1396
232
1397
23
1398
908
1399
678
1400
34
the growth rate is (this year - previous year)/previous year
could you please guide me how I can do this?
When I use the growth the data is like below

You can add a calculated column like this:
growth =
VAR _currentcount = 'Table'[count]
VAR _currentyear = 'Table'[year]
VAR _previouscount =
CALCULATE (
SELECTEDVALUE ( 'Table'[count] ) ,
ALL ( 'Table' ) ,
'Table'[year] = _currentyear - 1
)
RETURN
IF (
NOT ISBLANK ( _previouscount ) ,
DIVIDE ( _currentcount , _previouscount ) - 1
)
or a measure like this, to be used with your year dimension:
growth_measure =
VAR _currentcount = SELECTEDVALUE ( 'Table'[count] )
VAR _currentyear = SELECTEDVALUE ( 'Table'[year] )
VAR _previouscount =
CALCULATE (
SELECTEDVALUE ( 'Table'[count] ) ,
ALL ( 'Table' ) ,
'Table'[year] = _currentyear - 1
)
RETURN
IF (
NOT ISBLANK ( _previouscount ) ,
DIVIDE ( _currentcount , _previouscount ) - 1
)
Giving this result:
All depending on your needs.

Related

find percentage per unique fields value in a long-format table in powerbi dax

I have the following snip of a table in power bi:
columns: ['id','fields','io','status','value']
I would like to calculate for each unique value of the column field per id with a condition that the status value is complete.
+----+---------+---------+-----+
| id | field | status | % |
--------------------------------
| 112| zip | complete| 60 |
| 112| gender | complete| 54 |
...
| 245| zip | complete| 85 |
+----+=--------+---------+-----+
the idea is (sum of complete) / (sum of complete+missing+error) per id.
I am not sure how to approach this with a long format table.
try this :
Completed % =
CALCULATE (
SUM ( 'Table (2)'[value] ),
ALLEXCEPT ( 'Table (2)', 'Table (2)'[id], 'Table (2)'[fields] ),
'Table (2)'[status] = "Complete"
)
/ CALCULATE (
SUM ( 'Table (2)'[value] ),
ALLEXCEPT ( 'Table (2)', 'Table (2)'[id] )
)
You can use this code as a measure:
Completed_Percent =
VAR SummaryTable =
ADDCOLUMNS (
FILTER (
SUMMARIZE ( Table1, Table1[id], Table1[fields], Table1[status] ),
Table1[status] = "complete"
),
"%",
DIVIDE (
100 * CALCULATE ( SUM ( Table1[value] ) ),
CALCULATE ( SUM ( Table1[value] ), ALL ( Table1 ) )
)
)
VAR Result =
SUMX ( SummaryTable, [%] )
RETURN
Result
Then Create a table or Matrix, Put [id], [field],[status] into row area, and put "Completed_Percent" measure in the value area. Done!
If we test it:

ALL context removal does not apply

I have defined the following table :
The following measure does not work as expected :
VAR lt_MAX_DATE =
FILTER(
ALL( dim_CALENDAR[DATE] ) ,
dim_CALENDAR[DATE] = MAX( dim_CALENDAR[DATE] )
)
VAR lv_MAX_YEAR_DAY =
CALCULATE(
VALUES( dim_CALENDAR[YEAR_DAY] ) ,
ALL( dim_CALENDAR ) ,
lt_MAX_DATE
)
RETURN
lv_MAX_YEAR_DAY
as I get :
In my mind, I should get 10 for both rows of the Max Date ALL column, but this is not the case.
My question is : why does a dim_CALENDAR[YEAR] context apply even though I have used the ALL() function?
Thank you for your help.
If you want the DAX measure to return the max Year_day of maxYear by ignoring no matter what year is currently visible in the filter context, you can achieve it in many ways. Two of them are as below.
Measure1 =
VAR mxYr =
CALCULATE ( MAX ( dim_Calendar[Year] ), ALL ( dim_Calendar[Year] ) )
RETURN
CALCULATE (
MAX ( dim_Calendar[Year_day] ),
dim_Calendar[Year]=mxYr
)
Measure2 =
VAR mxYr =
CALCULATE ( MAX ( dim_Calendar[Year] ), ALL ( dim_Calendar[Year] ) )
RETURN
CALCULATE (
MAX ( dim_Calendar[Year_day] ),
TREATAS ( { mxYr }, dim_Calendar[Year] )
)
This expression
VAR lt_MAX_DATE =
FILTER(
ALL( dim_CALENDAR[DATE] ) ,
dim_CALENDAR[DATE] = MAX( dim_CALENDAR[DATE] )
)
is the same as
VAR YEARinMatrixRow = SELECTEDVALUE[dim_CALENDAR[YEAR]]
VAR lt_MAX_DATE =
CALCULATETABLE (
FILTER(
ALL( dim_CALENDAR[DATE] ) ,
dim_CALENDAR[DATE] = MAX( dim_CALENDAR[DATE] )
)
,dim_CALENDAR[YEAR] = YEARinMatrixRow
)
So, the result of the expression is the last date of the selected (in Row) year. You get a Row filtering.
The second expression filters the table by
ALL( dim_CALENDAR )
,lt_MAX_DATE
According to DAX priorities, first works ALL(dim_CALENDAR) , then you apply filter - lt_MAX_DATE
So, you get the dim_CALENDAR table, simply filtered by the last day of the year in a matrix row where you get a single value with the VALUES( dim_CALENDAR[YEAR_DAY] ).
You overite ALL( dim_CALENDAR ) by the - lt_MAX_DATE
Normaly, you will get an error with lv_MAX_YEAR_DAY syntax. Calculate returns scalar value, while VALUES() function returns a table even with 1 cell.
As #Mik says, you are restricting the context with
dim_CALENDAR[DATE] = MAX( dim_CALENDAR[DATE] )

DAX/PowerBI Rank taking a variable/parameter into account

I'm working on a ranking/scoring system and I'm missing the PERCENTRANK.INC function in powerBI. Instead I have worked out below formula which is the closest I can get.
Score =
DIVIDE (
RANKX (
FILTER ( 'Table', NOT ( ISBLANK ( [Sold amounts] ) ) ),
[Sold amounts],
,
ASC
) - 1,
COUNTROWS ( FILTER ( 'Table', NOT ( ISBLANK ( [Sold amounts] ) ) ) ) - 1
)
I really want to have the formula to take the type of "Fruit" into account in my scoring/ranking.
In short each fruit should be scored separately, with a range per fruit sold.
Could this somehow be done with a variable (VAR)?
Example of data:
This should work.
Score =
VAR fruit = 'Table'[Fruit]
VAR filteredTable = FILTER ( 'Table', NOT ( ISBLANK ( [Sold amount] ) ) && 'Table'[Fruit] = fruit)
RETURN
DIVIDE (
RANKX (
filteredTable,
[Sold amount],
,
ASC
) - 1,
COUNTROWS ( filteredTable ) - 1
)

Count of customers whose rating is lowered more than 3 this year

I am here with a DAX/PBI question.
I have a table that contains Customer number, rating date and rating. (which is shown below). Each customer has several rating notes in different dates, as shown below:
CustomerNumber RatingDate Rating
887 01.10.2020 2
887 31.12.2019 5
887 06.01.2020 3
887 31.12.2018 3
940 10.07.2020 14
940 31.12.2019 10
656 01.05.2020 8
656 31.12.2019 8
I want to create a measure and place it on a card that shows the count of customers whose rating dropped more than 3 levels in this year (compare between last rating in 2019 and last rating in 2020).
As in this example table, result should be 1 (cus. number 940)
However the measure that i wrote doesnt seem to be working: (blank result)
COUNTROWS(
FILTER('Rating Change';
IF(COUNTROWS(FILTER('Rating Change';'Rating Change'[Ratingdate].[Year]=2020))=0;BLANK();
IF(COUNTROWS(FILTER('Rating Change';'Rating Change'[Ratingdate].[Year]=2019))=0;BLANK();
CALCULATE(MAX('Rating Change'[Rating]);FILTER('Rating Change';'Rating Change'[Ratingdate].[Year]=2019)) -
CALCULATE(MAX('Rating Change'[Rating]);FILTER('Rating Change';'Rating Change'[Ratingdate].[Year]=2020))>3
)
)
Probably you have an error in your sample data, because 940 has increased his Level;
The solution could look like this:
measure = countrows(FILTER (
ADDCOLUMNS (
VALUES ( 'Rating Change'[CustomerNumber] ),
"maxRating",
CALCULATE (
MAX ( 'Rating CHange'[Rating] ),
FILTER (
ALL ( 'Rating Change'[RatingDate] ),
VAR _x =
CALCULATE (
MAX ( 'Rating Change'[RatingDate] ),
YEAR ( 'Rating Change'[RatingDate] ) = YEAR ( TODAY () )
)
RETURN
'Rating Change'[RatingDate] = _x
)
),
"maxRatingLY",
CALCULATE (
MAX ( 'Rating CHange'[Rating] ),
FILTER (
ALL ( 'Rating Change'[RatingDate] ),
VAR _x =
CALCULATE (
MAX ( 'Rating Change'[RatingDate] ),
YEAR ( 'Rating Change'[RatingDate] )
= YEAR ( TODAY () ) - 1
)
RETURN
'Rating Change'[RatingDate] = _x
)
)
),
[maxRatingLY] - [maxRating] > 3
)
)

How to distinctly count customer IDs that visited a store in a given quarter only if the same customer ID visited in the previous quarter

I have a table
+-----------+----------+--------+-------+---------+
|Customer ID|Visit Date|Category|Product|Served by|
+-----------+----------+--------+-------+---------+
|1001 |03/17/2019|A |P11 |Jone Doe |
|1003 |03/17/2019|D |P12 |Jone Doe |
|1006 |03/15/2019|C |P13 |Jone Doe |
|1009 |03/10/2019|G |P14 |Jone Doe |
|1011 |12/12/2018|H |P15 |Foo Bar |
|1003 |11/11/2018|D |P16 |Foo Bar |
|1006 |09/10/2018|C |P17 |Foo Bar |
|1009 |10/10/2018|G |P18 |Foo Bar |
+-----------+----------+--------+-------+---------+
there are 4 customers but only 2 (1003 and 1009) visited in the previous quarter.
I used DATESINPERIOD but it counts all distinctly between the preceding quarters (I have a designated date table).
1st approach
customers_count =
CALCULATE (
DISTINCTCOUNT[Customer ID],
DATESINPERIOD (
'Calendar'[Date],
ENDOFQUARTER ( 'Calendar'[Date] ),
-2,
QUARTER
)
)
2nd approach
customers_count 2Q =
VAR customers_count_1 =
DISTINCT ( FILTER ( VALUES ( Orders[Customer ID] ) ) )
VAR customers_count_2 =
CALCULATETABLE (
DISTINCT ( FILTER ( VALUES ( Orders[Customer ID] ) ) ),
DATEADD ( 'Calendar'[Date], -1, QUARTER )
)
RETURN
COUNTROWS ( INTERSECT ( customers_count_1, customers_count_2 ) )
The expected count is 2 for the last quarter.
Your second approach looks reasonable. Try it without DISTINCT and FILTER.
customers_count 2Q =
VAR customers_count_1 =
VALUES ( Orders[Customer ID] )
VAR customers_count_2 =
CALCULATETABLE (
VALUES ( Orders[Customer ID] ),
DATEADD ( 'Calendar'[Date], -1, QUARTER )
)
RETURN
COUNTROWS ( INTERSECT ( customers_count_1, customers_count_2 ) )
The VALUES function returns a list of distinct values of its column argument that are within its filter context.

Resources