In this example (Calculate ratio of Category Sales to Total Sales): https://learn.microsoft.com/en-us/dax/all-function-dax#example-1
Formula is:
=
SUMX(
ResellerSales_USD,
ResellerSales_USD[SalesAmount_USD]
)
/ SUMX(
ALL( ResellerSales_USD ),
ResellerSales_USD[SalesAmount_USD]
)
In this example (Calculate Ratio of Product Sales to Total Sales Through Current Year): https://learn.microsoft.com/en-us/dax/all-function-dax#example-2
Formula is:
=
SUMX(
ResellerSales_USD,
ResellerSales_USD[SalesAmount_USD]
)
/ CALCULATE(
SUM( ResellerSales_USD[SalesAmount_USD] ),
ALL( DateTime[CalendarYear] )
)
In the 2nd example why can we not use SUMX ALL similar to example 1 to remove the calendar year filter? Example:
=
SUMX(
ResellerSales_USD,
ResellerSales_USD[SalesAmount_USD]
)
/ SUMX(
ALL( DateTime[CalendarYear] ),
ResellerSales_USD[SalesAmount_USD]
)
Similarly, could 1st example be re-written using CALCULATE as:
=
SUMX(
ResellerSales_USD,
ResellerSales_USD[SalesAmount_USD]
)
/ CALCULATE(
SUM( ResellerSales_USD[SalesAmount_USD] ),
ALL( ResellerSales_USD )
)
The code
=
SUMX(
ResellerSales_USD,
ResellerSales_USD[SalesAmount_USD]
)
/ SUMX(
ALL( DateTime[CalendarYear] ),
ResellerSales_USD[SalesAmount_USD]
)
would not work, since the SUMX at the donominator is iterating over the column DateTime[CalendarYear], therefore no row context exists to make ResellerSales_USD[SalesAmount_USD] column accessible. Also, the relationship between Date and ResellerSales is one to many, it wouldn't be possible to use RELATED, but RELATEDTABLE and an aggregator would be required, like for instance
=
SUMX(
ResellerSales_USD,
ResellerSales_USD[SalesAmount_USD]
)
/ SUMX(
ALL( DateTime[CalendarYear] ),
SUMX( RELATEDTABLE(ResellerSales_USD), ResellerSales_USD[SalesAmount_USD])
)
This one instead is equivalent to the first example
=
SUMX(
ResellerSales_USD,
ResellerSales_USD[SalesAmount_USD]
)
/ CALCULATE(
SUM( ResellerSales_USD[SalesAmount_USD] ),
ALL( ResellerSales_USD )
)
Related
I have this DAX formula which is working fine, I want to add a date filter to filter for sales completed before DB Sales [date] 30/9/2022, but it does not like the date filters. Any help and directions appreciated.
Sales Completed =
IF.EAGER (
CALCULATE (
COUNTROWS ( 'DB Sales' ),
'DB Sales'[Status] = "Completed"
) + 0 = 0,
BLANK (),
CALCULATE (
COUNTROWS ( 'DB Sales' ),
'DB Sales'[Status] = "Completed"
) + 0
)
You need to convert your string to a date for comparison:
Sales Completed before Date =
VAR _rows =
CALCULATE (
COUNTROWS ( 'DB Sales' ),
'DB Sales'[Status] = "Completed",
'DB Sales'[Date] < DATEVALUE("30/9/2022")
)
RETURN
IF (_rows = 0, BLANK(), _rows)
I am new to dax, would like to create a measure that allows me to see how many companies sold to different combinations of countries. For example, how many companies sold to all countries, or how many companies sold to just country A and B. I have tried using filters, they always return blank values. All the data is in this one table, please see screen shot below. Will appreciate your help
screenshot for sample data
You want to calculate total sales for combinations, Write this 3 measures :
Total Sales For A =
CALCULATE (
[total sales],
CALCULATETABLE ( VALUES ( YourTbl[Company] ), YourTbl[Country] = "A" )
)
Total Sales For B =
CALCULATE (
[total sales],
CALCULATETABLE ( VALUES ( YourTbl[Company] ), YourTbl[Country] = "B" )
)
Total Sales For All(ABC) =
VAR OnlyA =
CALCULATETABLE ( VALUES ( YourTbl[Company] ), YourTbl[Country] = "A" )
VAR OnlyB =
CALCULATETABLE ( VALUES ( YourTbl[Company] ), YourTbl[Country] = "B" )
VAR OnlyC =
CALCULATETABLE ( VALUES ( YourTbl[Company] ), YourTbl[Country] = "C" )
VAR ABC =
INTERSECT ( INTERSECT ( OnlyA, OnlyB ), OnlyC )
VAR Result =
CALCULATE ( [total sales], ABC )
RETURN
Result
Hello Please try this:
1st Measure : Sales For Only A Country
SalesOnlyForA =
COUNTROWS (
CALCULATETABLE (
SUMMARIZE ( YourTbl, YourTbl[Company], YourTbl[Country] ),
YourTbl[Country] = "A"
)
)
2nd Measure : Sales For Only B Country
SalesOnlyForB =
COUNTROWS (
CALCULATETABLE (
SUMMARIZE ( YourTbl, YourTbl[Company], YourTbl[Country] ),
YourTbl[Country] = "B"
)
)
3rd Measure : Sales For All Countries:
SalesForAllCountries =
VAR OnlyA =
CALCULATETABLE ( VALUES ( YourTbl[Company] ), YourTbl[Country] = "A" )
VAR OnlyB =
CALCULATETABLE ( VALUES ( YourTbl[Company] ), YourTbl[Country] = "B" )
VAR OnlyC =
CALCULATETABLE ( VALUES ( YourTbl[Company] ), YourTbl[Country] = "C" )
RETURN
COUNTROWS ( INTERSECT ( INTERSECT ( OnlyA, OnlyB ), OnlyC ) )
Bonus- Extra :
If you want to see all in one code:
Full_Code =
VAR SalesOnlyForA =
COUNTROWS (
CALCULATETABLE (
SUMMARIZE ( YourTbl, YourTbl[Company], YourTbl[Country] ),
YourTbl[Country] = "A"
)
)
VAR SalesOnlyForB =
COUNTROWS (
CALCULATETABLE (
SUMMARIZE ( YourTbl, YourTbl[Company], YourTbl[Country] ),
YourTbl[Country] = "B"
)
)
VAR SalesOnlyForC =
COUNTROWS (
CALCULATETABLE (
SUMMARIZE ( YourTbl, YourTbl[Company], YourTbl[Country] ),
YourTbl[Country] = "C"
)
)
VAR OnlyA =
CALCULATETABLE ( VALUES ( YourTbl[Company] ), YourTbl[Country] = "A" )
VAR OnlyB =
CALCULATETABLE ( VALUES ( YourTbl[Company] ), YourTbl[Country] = "B" )
VAR OnlyC =
CALCULATETABLE ( VALUES ( YourTbl[Company] ), YourTbl[Country] = "C" )
VAR ABC =
COUNTROWS ( INTERSECT ( INTERSECT ( OnlyA, OnlyB ), OnlyC ) )
RETURN
ROW (
"Sales A", SalesOnlyForA,
"Sales B", SalesOnlyForB,
"Sales C", SalesOnlyForC,
"Sales All", ABC
)
Result_Set:
Im calculating number of months in two different years.That means if i select date filter from 2020 jan 1st to todate i need to show 2020 has 12 months and 2021 has 02 months todate from january.i want to show 02 cards seperately to show months.is there a way to do this? I tries Datediff. But it shows months count form 2020 to todate. Can someone help me to get this?
Thank
Assuming you only have a table containing only the 'Date'[Date] column, like generated by
Date = CALENDAR("2019-01-01", "2021-12-31")
you can write two measures, one to get the months of the last year in the selection and of the previous one
# Months =
VAR CurrentYear = YEAR( MAX( 'Date'[Date] ) )
VAR CurrentYearDates = FILTER( 'Date', YEAR( 'Date'[Date] ) = CurrentYear )
VAR Months = SELECTCOLUMNS( CurrentYearDates, "Month", MONTH( 'Date'[Date] ) )
RETURN
COUNTROWS( DISTINCT ( Months ) )
# Months PY =
VAR PY = YEAR( MAX( 'Date'[Date] ) ) - 1
VAR PYDates = FILTER( 'Date', YEAR( 'Date'[Date] ) = PY )
VAR Months = SELECTCOLUMNS( PYDates, "Month", MONTH( 'Date'[Date] ) )
RETURN
COUNTROWS( DISTINCT ( Months ) )
this allows to assign a measure per card
This could be simplified with a Date table with Year and Month
Date =
ADDCOLUMNS (
CALENDAR ( "2019-01-01", "2021-12-31" ),
"Year", YEAR ( [Date] ),
"Month", MONTH ( [Date] )
)
# Months =
VAR CurrentYear = YEAR( MAX( 'Date'[Date] ) )
RETURN
CALCULATE( DISTINCTCOUNT( 'Date'[Month] ), 'Date'[Year] = CurrentYear )
# Months PY =
VAR PY = YEAR( MAX( 'Date'[Date] ) ) - 1
RETURN
CALCULATE( DISTINCTCOUNT( 'Date'[Month] ), 'Date'[Year] = PY )
How to get the latest date with sales Amount for all the dates between min and max date with sales Amount. In the table, some Dates may have null Amount. Here is example with expected results:
Here is what I have tried. These are all DAX measures.
LastDate =
CALCULATE(
LASTDATE( Sales[Date] ),
REMOVEFILTERS( Sales[Date] )
)
LastNonBlank =
CALCULATE(
LASTNONBLANK( Sales[Date], [Sales] ),
REMOVEFILTERS( Sales )
)
MaxDate =
CALCULATE(
MAX( Sales[Date] ),
REMOVEFILTERS( Sales[Date] )
)
MaxDate_Filter =
CALCULATE(
MAX( Sales[Date] ),
FILTER( ALL( Sales ), Sales[Amount] > 0 )
)
And here is what I get with it:
So non of the measures produces the expected results.
Table to recreate problem:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjIwMtA1MAQiJR0lEIYLmCjF6iDJGwHl8EgbA+VM8cibAOWM8cibQoxXio0FAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [Date = _t, Amount = _t, #"Expected Result" = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Amount", Int64.Type}, {"Expected Result", type date}})
in
#"Changed Type"
Update
Here I found interesting reference that solved my problem:
https://www.sqlbi.com/articles/hiding-future-dates-for-calculations-in-dax/
We add calculated column to Sales table:
DatesWithSales =
var CalendarDate = Sales[Date]
return
CalendarDate <= CALCULATE( MAX( Sales[Date] ), FILTER( ALLSELECTED( Sales ), Sales[Amount] > 0 ) ) &&
CalendarDate >= CALCULATE( MIN( Sales[Date] ), FILTER( ALLSELECTED( Sales ), Sales[Amount] > 0 ) )
Then we use measure:
Expected Result =
CALCULATE(
MAX( Sales[Date] ),
CALCULATETABLE(
VALUES( Sales[Date] ), -- here can be whatever time intelligence function like SAMEPERIODLASTYEAR( Sales[Date] )
Sales[DatesWithSales] = TRUE()
)
)
you can try:
Expected Result =
var maxDate = CALCULATE(MAX(Sales[Date]), FILTER(Sales, NOT(ISBLANK(Sales[Amount]))))
return IF(Sales[Date]> maxDate,BLANK(),maxDate)
It first calcualates the maxDate based on all rows with a value in Amount and later fills the column with maxDate, only when Sales[Date] is smaller or equal.
Your MaxDate_Filter looks fine. If you want to blank out dates beyond that, then you can do
Expected Result =
VAR RowDate = SELECTEDVALUE ( Sales[Date] )
RETURN
IF ( RowDate <= [MaxDate_Filter], RowDate )
or, assuming you have defined an analogous [MinDate_Filter] and want to filter on both sides:
Expected Result =
VAR RowDate = SELECTEDVALUE ( Sales[Date] )
RETURN
IF ( RowDate <= [MaxDate_Filter] && RowDate >= [MinDate_Filter], RowDate )
Here I found interesting reference that solved the problem:
https://www.sqlbi.com/articles/hiding-future-dates-for-calculations-in-dax/
We add calculated column to Sales table. In real model, this column should be added to Calendar table.
DatesWithSales =
var CalendarDate = Sales[Date]
return
CalendarDate <= CALCULATE( MAX( Sales[Date] ), FILTER( ALLSELECTED( Sales ), Sales[Amount] > 0 ) ) &&
CalendarDate >= CALCULATE( MIN( Sales[Date] ), FILTER( ALLSELECTED( Sales ), Sales[Amount] > 0 ) )
Then we use measure:
Expected Result =
CALCULATE(
MAX( Sales[Date] ),
CALCULATETABLE(
VALUES( Sales[Date] ), -- here can be whatever time intelligence function like SAMEPERIODLASTYEAR( Sales[Date] )
Sales[DatesWithSales] = TRUE()
)
)
I have a table having customer transactions. I need to create a new column where, for each row:
If its the first appearance of a 'customer id', it will have "Onboarding"
If its the last appearance of a 'customer id', it will have "Offboarding"
The rest will be "Existing"
So following is the DAX Code i tried out:
Customer Churn =
IF (
Book[Date]
= LOOKUPVALUE ( Book[Date].[Date], Book[customer id], FIRSTDATE ( Book[Date] ) ),
"Onboarding",
IF (
Book[Date]
= LOOKUPVALUE ( Book[Date].[Date], Book[customer id], LASTDATE ( Book[Date] ) ),
"Offboarding",
"Existing"
)
)
But i am getting the following error:
The column 'Book[customer id]' either doesn't exist or doesn't have a relationship to any table available in the current context.
Can't think of using RELATED() as I'm referring the same table.
Where is the issue?
Any workaround if it's not possible to code it this way?
Thanks!
With some help I got the solution. Refer to dax/lookupvalue-function-dax, you will find out the errors in the original script. The search_columnName and search_value are a pair.
LOOKUPVALUE( <result_columnName>, <search_columnName>, <search_value>[, <search_columnName>, <search_value>]…)
So the formula can't return the right result.
LOOKUPVALUE ( Book[Date].[Date], Book[customer id], FIRSTDATE ( Book[Date] ) )
Solution:
Customer Churn =
VAR startDate =
CALCULATE ( FIRSTDATE ( Book[Date] ), ALLEXCEPT ( Book, Book[Customer Id] ) )
VAR endDate =
CALCULATE ( LASTDATE ( Book[Date] ), ALLEXCEPT ( Book, Book[Customer Id] ) )
RETURN
IF (
Book[Date]
= LOOKUPVALUE (
Book[Date],
Book[customer id], [Customer Id],
Book[Date], startDate
),
"Onboarding",
IF (
Book[Date]
= LOOKUPVALUE (
Book[Date],
Book[customer id], [Customer Id],
Book[Date], endDate
),
"Offboarding",
"Existing"
)
)