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:
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 trying to summarize the data with total sums till the min date selected in the slicer with one more condition. But somehow it does not sum up. what am i missing ?
Till Date Sum =
VAR _lastdate =
CALCULATE ( MIN ( 'Mizan Full'[Tarih] ), ALLSELECTED ( 'Mizan Full'[Tarih] ) ) - 1
RETURN
CALCULATETABLE (
SUMMARIZECOLUMNS (
'Mizan Full'[Firma Adı],
'Mizan Full'[Hesap No],
'Mizan Full'[Hesap Grup Adı],
"Önceki Toplam", SUM ( 'Mizan Full'[Rapor USD] )
),
'Mizan Full'[Hesap Grubu] = "100",
'Mizan Full'[Tarih] <= _lastdate
)
Edit : The problem is with the _lastdate, it calculates normally separately but when in the formula, it gets the minimum date of all data, not the selected one.
I also tried with the FILTER() as below, still not returns correct result.
Till Date Sum =
SUMMARIZECOLUMNS (
'Mizan Full'[Firma Adı],
'Mizan Full'[Hesap No],
'Mizan Full'[Hesap Grup Adı],
FILTER ( 'Mizan Full', 'Mizan Full'[Hesap Grubu] = "100" ),
FILTER (
'Mizan Full',
'Mizan Full'[Tarih]
<= CALCULATE ( MIN ( 'Mizan Full'[Tarih] ), ALLSELECTED ( 'Mizan Full'[Tarih] ) ) - 1
),
"Önceki Toplam", SUM ( 'Mizan Full'[Rapor USD] )
)
Please try this:
VERSION-1
Till Date Sum =
VAR _lastdate =
CALCULATE(MINX ( ALLSELECTED ( 'Mizan Full'[Tarih] ), 'Mizan Full'[Tarih] ))
RETURN
CALCULATETABLE (
ADDCOLUMNS (
SUMMARIZE (
'Mizan Full',
'Mizan Full'[Firma Adı],
'Mizan Full'[Hesap No],
'Mizan Full'[Hesap Grup Adı]
),
"Önceki Toplam", CALCULATE ( SUM ( 'Mizan Full'[Rapor USD] ) )
),
'Mizan Full'[Hesap Grubu] = "100",
'Mizan Full'[Tarih] <= _lastdate
)
VERSION-2
Till Date Sum =
VAR _lastdate =
CALCULATE (
SELECTEDVALUE ( 'Mizan Full'[Tarih] ),
MINX ( ALLSELECTED ( 'Mizan Full'[Tarih] ), 'Mizan Full'[Tarih] )
= MIN ( 'Mizan Full'[Tarih] )
)
RETURN
CALCULATETABLE (
ADDCOLUMNS (
SUMMARIZE (
'Mizan Full',
'Mizan Full'[Firma Adı],
'Mizan Full'[Hesap No],
'Mizan Full'[Hesap Grup Adı]
),
"Önceki Toplam", CALCULATE ( SUM ( 'Mizan Full'[Rapor USD] ) )
),
'Mizan Full'[Hesap Grubu] = "100",
'Mizan Full'[Tarih] <= _lastdate
)
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 )
)
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"
)
)