I have a table of defect data that I would like to create a MEASURE that gives me a count of defects for each month. I know I need to use a date table but my attempts thus far haven't worked out.
What I am looking for when this works is a simple count by month:
January 125
February 225
March 220
April 120
Defect Table
Date Table
Here is the Measure I was trying to build without any luck...
Monthly Defects =
// TOTALYTD(COUNT(Defects[Defect]), 'Date'[Date])
VAR defectDate = FIRSTDATE(Defects[Created Date])
VAR defectYear = YEAR(defectDate)
VAR defectMonth = MONTH(defectDate)
RETURN
CALCULATE (
COUNT(Defects[Defect]),
FILTER (
Defects,
Defects[Created Date] <= defectDate &&
(YEAR (Defects[Created Date]) = defectYear) && (MONTH(Defects[Created Date]) = defectMonth)
)
)
Here is what I am looking to do in the end.
If you simply want a count per month, then your measure should be
Monthly Defects=COUNTROWS(Defects)
This is assuming that you have a relationship between your defect table and your date table.
Related
I have a calculated column "LastSaleDate" that finds the last date with sales with the following dax expression:
LastSaleDate=LASTDATE(filter(ALL(Dim_Time[Date]),[Sales Amount] >0))
What I want to achieve next is to create another calculated column "LastSaleDateStartingFromYesterday". So for example if the current date is Monday and there are no sales on Sunday or Saturday it should return Friday as the last date with sales (See example below). It is possible that Saturday and Sunday have Sales so I cannot exlude/filter them out.
How to write such a dax expression ?
All tips, solutions and help are highly appreciated
Best regards, Rubrix
I found that your calculation for last sales date is not properly applying the filter for [Sales Amount] > 0. You can see this if you add an additional row for 2022-05-17 where [Sales Amount] = 0.
Here are the DAX formulas that worked for me:
LastSaleDate2 = CALCULATE(
MAX('Table'[Date]),
FILTER('Table','Table'[Sales Amount]>0)
)
LastSaleDateStartingFromYesterday2 = CALCULATE(
MAX('Table'[Date]),
FILTER('Table','Table'[Sales Amount]>0 && VALUE('Table'[Date]) < VALUE(TODAY()-1))
)
These can be converted to True/False by adding "= 'Table'[Date]" to the end of the formula.
You can add a calculated column:
PreviousSalesDate =
var sDate = Sales[Date]
var lDate = CALCULATE(max(Sales[Date]), FILTER(Sales, sDate > Sales[Date] && Sales[Sales Amount] > 0))
return lDate
We work with variables in the code. sDate is teh current date of the row. Next we get the max of all rows where the date is smaller than the sDate (all rows before) and the sales is bigger than zero.
By the data you have given we only get the 13th of may.
I am trying to get a rolling 3/6/12 month average of revenue by month using DAX in a SSAS Tabular model. There is a date table in my model and I have created inactive links between my fact table and my date table for each date in the fact (Date of Service, Invoice Date, etc.). I have created a measure that uses USERELATIONSHIP to activate the specific link I need.
Revenue by DOS:=
CALCULATE( [Total Gross Revenue],
USERELATIONSHIP(D_DATE[W_DT_ID],Fact_Charge[W_SERVICE_DT_ID])
)
Here is the code I am using to create the rolling average, which I copied from a SQLBI video on the same subject:
Net Revenue R3M:=
VAR NumOfMonths = 3
VAR LastSelectedDate = MAX(D_DATE[Calendar_Date])
VAR Period =
DATESINPERIOD( D_DATE[Calendar_Date], LastSelectedDate, -NumOfMonths, MONTH)
VAR Result =
CALCULATE(
AVERAGEX(
VALUES(D_DATE[Month Year]),
[Revenue by DOS]
),
Period
)
Return
Result
For some reason when I deploy the model and try to use it in Power BI, it runs this rolling average at the year level, but not the month. For instance, the Power BI matrix visual will show the year 2021 and will have a value that is equal to the average of the last 3 months of 2021, but the individual months show the same value that is contained in the Revenue by DOS measure itself.
Snip From Power BI
The goal is to have each individual month in the Revenue R3M column to be the 3 month average of the Revenue by DOS column.
I need to calculate headcount while keeping the measure sliceable by any dimension connected to the fact table. Given the nature of my tables and model, what I need to do is a point in time calculation on a Slowly Changing Dimension Type 2.
I managed to make it work using the function KEEPFITLERS, but I need a more scalable function that wouldn't require me to list all the dimensions I want to slice by.
Here is my PowerBI file with sample data: https://gofile.io/d/smS2Hr
Here is a simplified sketch (image) of my model: https://ibb.co/fQYpsdx
Background:
The first measure I am calculating is the number of Employees at the Start of the Period (Employees SoP). If the end-user selects in PowerBI the whole month of January 2020, the Start of the Period is Jan 1st, 2020. Hence, "Employees SoP" for the month of Jan 2020 will give the number of employees on Jan 1st, 2020.
The formula below calculates the correct values for Employees SoP:
Employees SoP =
VAR MinDate = MIN ( 'Date'[Date]) //Mininum date selected by end-user in PowerBI
VAR Result =
CALCULATE (
DISTINCTCOUNT(Fact[EmployeeId]),
FILTER(ALL('Fact'), 'Fact'[EffectiveStartDate] <= MinDate
&& IF(ISBLANK('Fact'[EffectiveEndDate]), date(2050,1,1), Fact[EffectiveEndDate]) > MinDate
))
RETURN
Result
The problem with the formula above is that, because of the ALL function, the measure is not sliceable by any dimension, i.e., Pay Class and Employment Status (the same number repeats itself).
Results:
Hence, I created this other measure using KEEPFILTERS, and it works perfectly.
Employees SoP KEEPFITLERS =
VAR MinDate = MIN ( 'Date'[Date]) //Mininum date selected by end-user in PowerBI
VAR Result =
CALCULATE (
DISTINCTCOUNT(Fact[EmployeeId]),
FILTER(ALL('Fact'), 'Fact'[EffectiveStartDate] <= MinDate
&& IF(ISBLANK('Fact'[EffectiveEndDate]), date(2050,1,1), Fact[EffectiveEndDate]) > MinDate
), KEEPFILTERS(PayClass), KEEPFILTERS(EmploymentStatus))
RETURN
Result
The problem with this formula is that I have to list all the dimensions I want to slice by ( e.g., PayClass, EmploymentStatus) inside the DAX formula. This is not very scalable.
I did some experimenting with REMOVEFILTERS but it looks like it does not work with DirectQuery for now, so it wouldn't solve my production problem. Link:
https://learn.microsoft.com/en-us/dax/removefilters-function-dax
QUESTION:
How can I write this measure using an alternative to KEEPFILTERS with which I wouldn't have to list each dimension I want to slice by?
Thank you!
I just managed to solve my problem. I made both relationships to the Dates table "inactive". With that, I could remove the "ALL" function in the DAX formula and now it not only calculates the correct values, but it also slices nicely. I will have to use the USERELATIONSHIP function to calculate more complex measures but, in most of the cases, this simple solution works like a charm.
Employees SoP without ALL =
VAR MinDate = MIN ( 'Date'[Date]) //Mininum date selected by end-user in PowerBI
VAR Result =
CALCULATE (
DISTINCTCOUNT(Fact[EmployeeId]),
FILTER('Fact', 'Fact'[EffectiveStartDate] <= MinDate
&& IF(ISBLANK('Fact'[EffectiveEndDate]), date(2050,1,1), Fact[EffectiveEndDate]) > MinDate
))
RETURN
Result
I have the following tables:
Revenue
Branch
Date
I have a table viz with branch name, % over last year for revenue
Here, my calculations are correct and numbers are correct as per requirement.
DAX I am using:
% over Last Year = IFERROR(
([Revenue 2019 YTD] / [Total Revenue 2018 for YTD]) -1,
BLANK())
Problem:
For 3 branches, these branches were acquired mid-year on 2018 and only has data from July of 2018.
When I am calculating data for % over last year, the numbers are incorrect for these branches as they only had partial data on 2018 and complete data ( Jan to current month) in 2019.
I need help on how I can calculate the % over last year also while considering the min date of 2018 for some branches that were acquired mid-year in 2018.
The solution to my question:
This Year YTD branch Growth with Partial Data =
var _thisyear = YEAR([Today])
var _currentweek = WEEKNUM([Today])
// last year min date
var _minweek =
CALCULATE(
SUMMARIZE(
Revenue,
"Min Date lY", CALCULATE(MIN(Revenue[weeknum])))
, FILTER(WeekCalendar, WeekCalendar[CalendarYear] = _thisyear - 1
))
return
SUMx(
SUMMARIZE(Revenue,
Revenue[Weekkey],
"Revenue YTD",
CALCULATE(
SUM(Revenue[Revenue]),
FILTER(Revenue, Revenue[weeknum] <= _currentweek),
FILTER(Revenue, Revenue[Year] = _thisyear),
FILTER(Revenue, Revenue[weeknum] >= _minweek), GROUPBY(branch, branch[Branchname])
)
),
[Revenue YTD]
)
If anyone has any suggestions to my DAX, Please let me know as well.
I am working in POWER BI and trying to calculate a DAX expression for the rolling total of the previous month. I have a filter where I select a certain month, I would like to calculate the rolling total for the previous month.
Below is the calculation that works perfectly to calculate the rolling total for the selected date range.
How can I calculate the previous months rolling total?
Rolling_Total_Current_Month = CALCULATE(
SUM(SalesInvoice[Sales])
,FILTER(ALLSELECTED(SalesInvoice), (SalesInvoice[Date]) <= MAX(SalesInvoice[Date])))
Here is a sample of my data, I have sales per day, for multiple categories, (in fact i have a couple more columns of details but this is simplified)
Date Day Amount Category
1/1/2016 1 100 A
1/1/2016 1 120 B
1/1/2016 1 90 C
1/2/2016 2 500 A
1/2/2016 2 321 B
1/2/2016 2 143 C
So far I have come up with an equation to solve the rolling total, but when I try to slice is and view the rolling total of a single category it does not work for the previous month. I just keeps the original rolling total for the previous month.
Here is the equation for the rolling total previous month that works. But does not recalculate a rolling total for the previous month once sliced based on category.
PREVIOUS_MONTH_ROLLING_TOTAL =
CALCULATE(
[Current Sales]
,FILTER(
ALL( Orders )
,Orders[MonthNumber] = MAX( Orders[MonthNumber] ) - 1
&& Orders[Day] <= MAX( Orders[Day] )
)
)
I have solved how to get the previous months rolling total.
You must do three things. First create a Month Number column in your data sheet (this is used as an integer to subtract 1 month from). You must also create a days column as well.
Then create a measure for Current Sales or whatever your value is.
Create a measure for the current month sales
Current Sales = SUM(Orders[Amount])
Then this equation.
PREVIOUS_MONTH_ROLLING_TOTAL =
CALCULATE(
[Current Sales]
,FILTER(
ALL( Orders )
,Orders[MonthNumber] = MAX( Orders[MonthNumber] ) - 1
&& Orders[Day] <= MAX( Orders[Day] )
)
)
The Idea of this equation is to be able to display the previous months rolling total on a chart with the X axis as "DAY" (so 1-31) Then you can view the current month, previous month, same period last year all on the same chart or table.
Try something along these lines:
Rolling_Total_Previous_Month =
VAR CurrentMonth = MAX(SalesInvoice[Date])
VAR PreviousMonth = EOMONTH(CurrentMonth,-1)
RETURN CALCULATE(SUM(SalesInvoice[Sales]), SalesInvoice[Date] <= PreviousMonth)
To start of, I have a data like this in a table called as Orders-
Date Amount
12/12/2017 100
12/12/2017 200
12/12/2017 300
1/1/2018 400
1/1/2018 500
I first create a calculated column called as Year & Month by using the formula:-
Year = YEAR(Orders[Date])
Month = FORMAT(Orders[Date],"mmmm")
Then I create a column called as Month Number which will be helpful for sorting when more than one year is involved in the table and as well as to Identify the Previous Months.
MonthNumber = DATEDIFF(Min(Orders[Date]),Orders[Date],MONTH)
Current Month Sales can be a measure or a Calculated column. Qn the Question, you had your answer for current month sales via a calculated column and if you want to go for a measure then something like this would work on a summary table.
Current Month Sales = SUm(Orders[Amount])
I would also create a column called as Key:-
Key = Orders[MonthNumber] & Orders[Category]
Now, for the Previous Month Sales, I would create a measure that looks for selected MonthNumber that we created.
Previous Month Sales =
Var SelectedCategory = SELECTEDVALUE(Orders[Category])
Var SelectedMonthNumberr = SELECTEDVALUE(Orders[MonthNumber]) - 1
Var ReqKey = SelectedMonthNumberr & SelectedCategory
Return
IF(ISBLANK(SelectedCategory) <> True(),
CALCULATE(SUM(Orders[Amount]),FILTER(ALL(Orders), Orders[Key] = ReqKey)),
CALCULATE(SUM(Orders[Amount]),FILTER(ALL(Orders), Orders[MonthNumber] = SelectedMonthNumberr)))
or to your Measure
PREVIOUS_MONTH_ROLLING_TOTAL =
CALCULATE(
[Current Sales]
,FILTER(
ALL( Orders )
,Orders[MonthNumber] = MAX( Orders[MonthNumber] ) - 1
&& Orders[Day] <= MAX( Orders[Day] )
)
)
You can just add another filtering item as && Orders[Category] = SELECTEDVALUE(Orders[Category]) but won't work when you don't have any categories selected or on a table or visual which doesn't have categories. So, you would need to define an if else logic here as I have quoted on my measure formula.
Do let me know, if this helps or not.