Power BI / DAX show count of distinct values in column - powerbi

I'd like to expand the solution on this page.
The original solution is given in Power query. But I'd like a DAX solution...
I've created a table from the fields Source and Preparer. If I want to see those sources where there is only one preparer what's is the best way to do it via DAX?
Like the Sources "MN", "RT" and "PO".
Source
Preparer
AB
June
AB
Jane
MN
June
SS
Kim
SS
Lee
SS
Jim
RT
Kim
PO
June
PO
June
RT
Kim
The outcome I'm looking for is like:
Source
Preparer
Number
MN
June
1
RT
Kim
1
PO
June
1
DAX that comes close looks like:
TableResult =
FILTER (
SUMMARIZECOLUMNS (
'Table'[Source],
"Number", DISTINCTCOUNT ( 'Table'[Preparer] )
),
[Number] = 1
)
This gives the source and the number, but not the Preparer....
Any ideas?

Please try this
newMeasure =
CALCULATE (
DISTINCTCOUNT ( 'Table 1'[Preparer] ),
FILTER (
GROUPBY ( 'Table 1', 'Table 1'[Source], 'Table 1'[Preparer] ),
CALCULATE (
DISTINCTCOUNT ( 'Table 1'[Preparer] ),
ALLEXCEPT ( 'Table 1', 'Table 1'[Source] )
) = 1
)
)

Related

power bi dax, sum up all latest monthly entries

Hi I have a data table in powerbi structured
id date data
1 2022-10-30 123
1 2022-11-01 130
1 2022-11-30 456
the data spans multiple user ids and multiple years and it the values are cumulative (like minutes on a phone plan for instance). This is not the real data
I want to add up the end of month data. In the ideal case, my table would be complete and 2022-10-31 would exist for instance, then I could do
Measure =
CALCULATE(
SUM( 'Table'[data] ),
'Table'[dates] = EOMONTH( 'Table'[dates],0 )
)
This returns 456 but I want 579 (123+456). So i cannot use EOMONTH
I think the answer is some combination of the dax above and
FILTER( Table, Table[date] = MAX( Table[date] ) )
Though if I paste that in solo, it grabs the actual latest date only, not all monthly latest dates
Also I will use slicers on user ID's in case that changes the DAX
Please use this measure to get what you need:
Measure_ =
VAR TblSummary =
ADDCOLUMNS ( YoursTable, "EOM", CALCULATE ( ENDOFMONTH ( YoursTable[date] ) ) )
RETURN
SUMX ( TblSummary, IF ( [EOM] = [date], [data] ) )
If we test our above measure on a table visual:

Moving Annual Total with DAX Power BI

I'm trying to calculate MAT (Moving Annual Total) using DAX, but can't realize exactly what I want.
I have the data as below.
What I'm trying to is calculate the total of treatment for each 12 month, like "Jan 21 - Dec 21" which has 'date' from 2020/1/1 to 2020/12/1. i.e. 'A' appears 4 times in that period, so the result will be like below.
Then I'd like to continue this for each latest 12 months, and finally visualize it like below.
I've read that I should use CALCULATE and DATESPERIOD in DAX, can't calculate exactly though. The following code is the one I tried and failed.
Moving Annual Total = CALCULATE(
COUNTA('2017-2022Q1'[idnum]),
DATESINPERIOD('2017-2022Q1'[mat].[Date], LASTDATE('2017-2022Q1'[mat].[Date]), 12, MONTH))
Could someone kindly give me an advise to realize this?
Thanks.
*This is the sample file.
https://drive.google.com/file/d/1gDNeBe5KiKBqx3cZ7G0SMiSQ23w96NF4/view?usp=sharing
In your dax measure, I recommend you first to create a date table and create a one-to-many relationship with the fact table(your table: '2017-2022Q1') ; then filter the date table in your calculate measure, not the fact table('2017-2022Q1') directly as you did here. You should follow the best practice.
For Example: How to create a date table using dax:
Date =
VAR MinYear = YEAR ( MIN ( '2017-2022Q1'[date] ) )
VAR MaxYear = YEAR ( MAX ( '2017-2022Q1'[date] ) )
RETURN
ADDCOLUMNS (
FILTER (
CALENDARAUTO( ),
AND ( YEAR ( [Date] ) >= MinYear, YEAR ( [Date] ) <= MaxYear )
),
"Calendar Year", "CY " & YEAR ( [Date] ),
"Month Name", FORMAT ( [Date], "mmmm" ),
"Month Number", MONTH ( [Date] )
)
Your final code could be like this:
Moving Annual Total = CALCULATE(
COUNTA('2017-2022Q1'[idnum]),
DATESINPERIOD('Date'[Date], LASTDATE('Date'[Date]), -12, MONTH)
)
if you define the start date using the lastdate() function, then It returns the last date in your filter context. you should also specify the interval as (-12) month to extract all dates within 1 year period.
Hope It helps.

Power bi - Getting the most recent value from another table

Hi I'm a beginner in Power bi
I have two tables
Table 1 has Dates, Unique IDs and Emails
Table 2 has list of Unique IDs same as the ones in table 1
Using DAX, I want to add a calculated column to the 2nd table to get the most recent email from table 1 based on the unique id and also avoid Email Values
Thank you.
with DAX measure - if both tables have a relationship
Measure1 =
CALCULATE (
MAX ( 'Table 1'[Email] ),
FILTER (
'Table 1',
'Table 1'[Date]
= CALCULATE (
MAX ( 'Table 1'[Date] ),
ALLEXCEPT ( 'Table 1', 'Table 1'[Unique_ID] )
)
)
)
with DAX calculated column - if both tables have a relationship
Column1 =
CALCULATE (
CALCULATE (
MAX ( 'Table 1'[Email] ),
FILTER (
'Table 1',
'Table 1'[Date]
= CALCULATE (
MAX ( 'Table 1'[Date] ),
ALLEXCEPT ( 'Table 1', 'Table 1'[Unique_ID] )
)
)
)
)
with DAX measure - if both tables have no relationship
Measure2 =
CALCULATE (
MAX ( 'Table 1'[Email] ),
FILTER (
'Table 1',
'Table 1'[Date]
= CALCULATE (
MAX ( 'Table 1'[Date] ),
ALLEXCEPT ( 'Table 1', 'Table 1'[Unique_ID] )
)
),
TREATAS ( VALUES ( 'Table 2'[Unique_ID] ), 'Table 1'[Unique_ID] )
)
with DAX calculated column - if both tables have no relationship
Column2 =
CALCULATE (
CALCULATE (
MAX ( 'Table 1'[Email] ),
FILTER (
'Table 1',
'Table 1'[Date]
= CALCULATE (
MAX ( 'Table 1'[Date] ),
ALLEXCEPT ( 'Table 1', 'Table 1'[Unique_ID] )
)
),
TREATAS ( VALUES ( 'Table 2'[Unique_ID] ), 'Table 1'[Unique_ID] )
)
)
Oh sorry I just realized you're already having a table2. Now I've split the answer in two party. New Column and New Table.
Creating NEW COLUMN
In this case you could try:
Most_Recent_Mail = SELECTCOLUMNS(TOPN(1,FILTER(table1, table1[Unique_ID] = table1[Unique_ID]), table1[Date]), "mail", Tabelle1[mail])
Creating NEW TABLE
I copied your table:
Now we can create a new table:
And use the following DAX code to fill this table:
New_Table = SUMMARIZE(table1,table1[Unique_ID], "Most_Recent_Mail",
CALCULATE(VALUES(table1[mail]), FILTER(all(table1), table1[Date] = max(table1[Date]))))
SUMMARIZE is like a group function.
With CALCULCATE you can create expressions in a filtered context.
With FILTER you can create a new context/subset.
ALL is ignoring all existing filters an returns the full dataset.
Result:
PS: Just to understand. If you only wanted the date, the formula would be much shorter
table2 = SUMMARIZE(table1,table1[Unique_ID], "Max_Date",
max(table1[Date]))
And if you would like to have both, you can add as much columns you want:
New_Table = SUMMARIZE(table1,table1[Unique_ID],
"Max_Date", max(table1[Date]),
"Most_Recent_Mail",
CALCULATE(VALUES(table1[mail]), FILTER(all(table1), table1[Date] = max(table1[Date]))))

dax - counting rows between dates

I have a table like
Account Open Close
1 01/01/2018 01/01/2019
2 01/01/2018 01/01/2020
3 01/01/2019 01/01/2021
4 01/01/2021
5 01/01/2019 01/01/2020
I'm interested in counting the number of accounts that are still active at the end of each year:
Year Count
2018 2
2019 3
2020 1
2021 1
I'm not sure if this can be derived from the Account table itself, so I created a date table with dates spanning many years. I added a column like
active_accounts = countrows ( Accounts, FILTER ( Accounts[Open] >= Date_table[Date] && Date_table[Date] < Accounts[Close]
The formula seemed to be working as an added column but took extremely long to calculate as the date table contains many dates. So I tried to use the formula as a DAX measure, but it seems to have trouble comparing columns between more than one table:
a single value for column 'Date' in table 'date_table' can't be determined. This can happen when a measure refers to a column containing many values without specifying aggregation
What's the simplest way to accomplish counting the number of active accounts in a particular year? Can this be done without a date table?
edit: enclosing date_table[date] with min() and max() makes the measure valid, but the figures are not right.
-further research indicates this might require CROSSJOIN()
edit: it looks like this can be accomplished by creating a cartesian product b/w the date_table and Account by FILTERING on where Date_table.Date is greater than Open but less than Close
You have already created a Calendar table and you can achieve the end goal with the following measure
_mX:=
VAR _1 =
GENERATEALL (
'fact',
DATESBETWEEN ( 'Calendar'[Calendar_Date], 'fact'[Open], 'fact'[Close]-1 )
)
VAR _2 =
ADDCOLUMNS (
_1,
"Calendar_Year",
CALCULATE (
MAXX (
FILTER ( 'Calendar', 'Calendar'[Calendar_Date] = [Calendar_Date] ),
'Calendar'[Calendar_Year]
) + 0
)
)
VAR _3 =
SUMMARIZE ( _2, [Calendar_Year], [Account] )
VAR _4 =
GROUPBY ( _3, [Calendar_Year], "count", COUNTX ( CURRENTGROUP (), [Account] ) )
VAR _5 =
ADDCOLUMNS (
'Calendar',
"ct",
CALCULATE (
MAXX (
FILTER ( _4, [Calendar_Year] = MAX ( 'Calendar'[Calendar_Year] ) ),
[count]
)
)
)
RETURN
MAXX ( _5, [ct] )
The measure is depended upon a calendar table with minimum columns like following and calendar has no relationship to fact
| Calendar_Date | Calendar_Year |
|---------------|---------------|
| 1/1/2018 | 2018 |

Filtering Before Groupingby / Summarize in Powerbi

I am having some troubles in grouping and filtering in powerbi. I want to be clear about the question so, my goal is to make everything on DAX and not using the filters in the reports. I am doing this because I will create other tables that will relate to this one.
So, let´s say I have one table like this called sales:
Order Customer Product Date Amount Type
A001 John TV 01/02/2019 200,00 ok
A002 Mark Chair 10/02/2019 150,00 ok
A003 John Bed 15/02/2019 50,00 Cancelled
A004 Mark TV 17/02/2019 75,00 ok
A004 Susan Table 19/02/2019 20,00 ok
A005 John Pillow 21/02/2019 50,00 ok
I want to get another table like this:
Customer Orders Last Order First Order Amount Type
John 2 21/02/2019 01/02/2019 250,00 ok
John 1 15/02/2019 15/02/2019 50,00 Cancelled
Mark 2 17/02/2019 10/02/2019 225,00 ok
Susan 1 19/02/2019 19/02/2019 20,00 ok
So, if I did not considered if the product was cancelled or not, the formula to create another table would be:
GROUPBY = (Sales;
'sales'[Customer]
"orders"; countx(currentgroup();'sales'[order]);
"last_order";MAXX(currentgroup();'sales'[Date]);
"first_order";MINX(currentgroup();'sales'[Date]);
"Amount";SUMX(currentgroup();'sales'[Amount]))
The question is, how can I groupby the type and understand if the order was cancelled or not?
tks
Personally, I prefer SUMMARIZECOLUMNS to GROUP BY in simple situations as it's less verbose.
Summary =
SUMMARIZECOLUMNS (
Sales[Customer],
Sales[Type],
"orders", COUNT ( Sales[Order] ),
"last_order", MAX ( Sales[Date] ),
"first_order", MIN ( Sales[Date] ),
"Amount", SUM ( Sales[Amount] )
)
You can simply add "Type" as a grouping field:
Summarized Sales =
GROUPBY (
'sales',
'sales'[Customer],
'sales'[Type],
"orders", COUNTX ( CURRENTGROUP (), 'sales'[order] ),
"last_order", MAXX ( CURRENTGROUP (), 'sales'[Date] ),
"first_order", MINX ( CURRENTGROUP (), 'sales'[Date] ),
"amount", SUMX ( CURRENTGROUP (), 'sales'[Amount] )
)
Result: