I replicated an issue I am having with the 'Adventure Works DW 2020' pbix file, so if my analysis seems a little out of context, please understand this example is not the true data I am working with. The pbix I used can be downloaded here:
https://drive.google.com/file/d/1vn6CluiE5rrAF3UjYPh5ejb93H2JX6IX/view?usp=sharing
My goal is to create a measure that can flag the subset of records that I want to use for a matrix visual.
I created the following measure with notes in the syntax:
VAR TABLEVAR =
SELECTCOLUMNS(
FILTER(
SUMMARIZE(
CALCULATETABLE(Sales/*Apply several filters to Sales table*/
,NOT Sales[CustomerKey] = -1
,Sales[orderdatekey] > 20180731
,Sales[orderdatekey] < 20190601
)
,[CustomerKey]/*Count the number of products per customer*/
,"Count",COUNT(Sales[ProductKey])
)
,[Count] > 1/*Only keep customers that bought more than 1 product*/
)
,[CustomerKey] /*Select the identifiers of the desired customers*/
)
RETURN
{
SWITCH(TRUE()
,SELECTEDVALUE(Sales[CustomerKey]) IN TABLEVAR/*Flag the customers that were identified in the previous table*/
,1,BLANK()
)
}
Now, in the PowerBI Matrix visual, this seems to work at first:
I had successfully flagged the desired output. Now I just have to filter for the 'Analysis' measure to be 'Not Blank', but then this happens:
Now removing that filter and going down a level:
So you see, the measure does not evaluate at the record level of the table. Does anyone understand the concept I am missing here? I have tried all kinds of different measures but it all comes down to the same problem about flagging different levels of analysis.
Ideally, the output would only include the following(circled in green):
These are the records that are within the date filters I put into the CALCULATETABLE() arguments.
Any help or insight with this problem would be greatly appreciated. Thank you
I'm not 100% clear what you're trying to do but please try the following and see if it helps.
Analysis =
VAR TABLEVAR =
SELECTCOLUMNS(
FILTER(
SUMMARIZE(
CALCULATETABLE(Sales
,NOT Sales[CustomerKey] = -1
,Sales[orderdatekey] > 20180731
,Sales[orderdatekey] < 20190601,
REMOVEFILTERS()
)
,[CustomerKey]
,"Count",COUNT(Sales[ProductKey])
)
,[Count] > 1
)
,[CustomerKey]
)
RETURN
//CONCATENATEX(TABLEVAR, [CustomerKey], ",")
SWITCH(TRUE()
,SELECTEDVALUE(Sales[CustomerKey]) IN TABLEVAR
,1,BLANK()
)
Related
Given the following data model:
I need to build a report that will display the following attributes:
As you see, I need to provide an attribute from the SalesOrder table [InternDocumentNumber[, so the visual will have grain on the order level.
Now, the problem is with measure [first order date v1] that should calculate the first order date made by the customer and display this value for all different orders from the same customer.
So far, I build the following measure
first order date v1 = CALCULATE (
FIRSTDATE( SalesOrderDate[SalesOrderDate]),
USERELATIONSHIP( SalesOrder[OrderDate], SalesOrderDate[SalesOrderDate]),
CROSSFILTER ( SalesOrder[OrderDate], SalesOrderDate[SalesOrderDate],both ),
ALL(SalesOrder)
)
However, this measure calculates forever, ending with the error:
Could you please advise me on how to write this measure, so it will perform better?
EDIT
Let me use an example from DAX.DO to be more clear on what I would like to get. Below is a screen of query and the result
What I would like to achieve is a measure, that will show me the min date for order on a customer level, and not the order level, as it is now. In other words, values in the red rectangle should be the same for customer 6, regardless of the grain of the table. Is this possible in DAX at all?
Reference to DAX.DO snippet:
https://dax.do/wxU6NNRHrencrg/
EDIT 2
Actually, I am able now to design a measure that solves the problem, however it performs very bad (timeouts in the end)
Here is the code screen and the DAX.DO reference
https://dax.do/wxU6NNRHrencrg/
You can try this:
CALCULATE (
MIN ( Sales[Order Date] ),
ALLEXCEPT ( Sales, Customer[CustomerKey] )
)
I have a table that looks like this. Table Screenshot
"FY 20-21 (Budgeted)", "FY21 Approved Budget" and "Revised Budget" are columns coming from three different data sources that I appended into one table. There isn't always data in all three of these columns, so I created a new column to consolidate the data with the following formula:
FY 20-21 Budget =
if(
and(
isblank('Comprehensive Budget'[FY 20-21 (Budgeted)]),
isblank('Comprehensive Budget'[FY21 Approved Budget])
),
'Comprehensive Budget'[Revised Budget],
if(
and(
isblank('Comprehensive Budget'[FY21 Approved Budget]),
isblank('Comprehensive Budget'[Revised Budget])
),
'Comprehensive Budget'[FY 20-21 (Budgeted)],
'Comprehensive Budget'[Revised Budget]
)
)
If both Budgeted and Approved are blank, use Revised.
If not, if both Revised and Approved are blank, use Budgeted.
If not, use Revised.
But if you look on the screenshot, if NONE of the columns are blank, it gives me Revised plus Budgeted. Where is the problem in my formula?
I have added your data here and found your Measure is perfectly returning your expected data as shown in the below image-
I Guess, there are some Aggregation issue in your case. You can right click on all column in the table visual properties and select Don't Summarize from the options. This should solve your issue I hope.
I have a table like this
Role Skills Resource
Data Analyst R A
Data Analyst Python A
Data Analyst SQL B
Business Analyst SQL A
My Skills are on filter. I have multiple visuals on the dashboard.
And If I select SQL and Python then the results of both Data Analyst and Business Analysts are getting displayed in the visual.
But, I want it to display only the Data Analyst results because only Data Analyst has all the selected skills.
To achieve this, I think of creating a measure and putting it on visual level filter in each of the visual might help.
Update :- If I select SQL here, I get 2 distinct resources on my card visual which is relevant to resources, but If I select SQL and Python - I get 0 Resources on my card visual which is relevant to resources and 1 role count which is relevant to roles on the Role measure.
Kindly help me with creating that measure.
Perhaps someone will suggest a more elegant way to do it; I came up with the following ideas.
Create a measure (I'll call your table "Data"):
Has All Selected Skills
=
VAR
Selected_Skills = ALLSELECTED ( Data[Skills] )
VAR
Role_Skills = CALCULATETABLE ( VALUES ( Data[Skills] ), ALL ( Data[Skills] ) )
VAR
Missing_Skills = COUNTROWS ( EXCEPT ( Selected_Skills, Role_Skills ) )
RETURN
IF ( NOT ( Missing_Skills ), 1 )
If the measure is placed in a visual against Roles, it'll produce the following results:
The way this code works:
First, we store all selected skills in a variable "Selected_Skills";
Second, we store all skills available for a role in a variable "Role_Skills". We must use ALL(Data[Skill]) to ignore the skill slicer selections;
Third, since both variables above are tables, we can use EXCEPT function to find how they are different. Here, we tell DAX to find what records in Selected_Skills don't exist in Role_Skills. Store the result in a variable "Missing_Skills".
Finally, if Missing_Skills is zero, it means that the role has all selected skills, and we flag it as 1 (although you might use True/False, etc).
The problem I see with this approach is that if Skill selector has no selection (shows "all skills"), then the formula might return blank for all roles, and all your visuals will be blank. Technically, it's correct - it's essentially saying that no roles have all skills. But if that's not the behavior you want, consider a slightly modified approach:
Missing Skills Count
=
VAR
Selected_Skills = ALLSELECTED ( Data[Skills] )
VAR
Role_Skills = CALCULATETABLE ( VALUES ( Data[Skills] ), ALL ( Data[Skills] ) )
VAR
Missing_Skills = COUNTROWS ( EXCEPT ( Selected_Skills, Role_Skills ) )
RETURN
Missing_Skills + 0
The formula uses the same logic, only returns the number of missing skills per role, instead of a true/false status. It will allow you to show a list of skills, sorted by the number of missing skills vs the selected skill set:
You can still use it to filter your visuals; the advantage is that it's never blank, even if all skills are selected:
It also gives you a capability to see what roles are the closest to meeting the requirement, even if none matches it perfectly; might be a desirable feature.
Final note: in all these reports, I have no subtotals and totals, assuming that they are not important. If you do need them, then the formulas might need to be modified to meet your requirements for the totals (depending on what you want to show there).
Using DAX to identify first instance of a record
I'm faced with trying to identify the first instance in a database where someone (identified by the ID column) has purchased a product for the first time. It's possible for said person to purchase the product multiple times on different days, or purchase different products on the same day. I drummed up an excel formula that gets me there, but am having trouble translating into DAX.
=COUNTIFS(ID,ID,PurchaseDate,"<="&PurchaseDate,Product,Product)
Which results in the correct values in the "First Instance?" Column.
Ideally I won't have to hardcode values, as I would like to use the "Product" column as a parameter in the future. If there are other suggests aside from translating this in DAX, that would also be appreciated! (IE using filters, or other tools in PowerBI)
Thanks in advance!
This is very similar to an answer I gave to another question (which you can find here).
In that question, the request was to see a running count of rows for the given row's criteria (product, year, etc.). We can modify that slightly to get it to work in your problem.
This is the formula I provided in the answer I linked above. The basic concept is to use the EARLIER functions to get the value from the row and pass it into the filter statement.
Running Count =
COUNTROWS(
FILTER(
'Data',
[ProductName] = EARLIER([ProductName]) &&
[Customer] = EARLIER([Customer]) &&
[Seller] = EARLIER([Seller]) &&
[Year] <= EARLIER([Year])
)
)
What I would suggest for your problem is to create this as a TRUE/FALSE flag by simply checking if the running count is 1. This formula will evaluate to a Boolean flag.
First Instance =
COUNTROWS(
FILTER(
'Data',
[ID] = EARLIER([ID]) &&
[Product] = EARLIER([Product]) &&
[Purchase Date] <= EARLIER([Purchase Date])
)
) = 1
I have got this following SQL query that gives me the correct value from the database.
SELECT
SUM( DISTINCT_ORDER_NUMBERS )
FROM
(
SELECT STORE_KEY,
COUNT( DISTINCT TRANSACTION_NUM ) AS DISTINCT_ORDER_NUMBERS,
DATE_KEY,
TRANSACTION_TYPE_KEY
FROM Pos_Data
GROUP BY STORE_KEY,
DATE_KEY,
TRANSACTION_TYPE_KEY
)
AS A
I am however facing challenges writing a DAX formula for a measure in Power BI Here is what I have tried so far but I get an error.
Total Number Of Orders
VAR _TotalOrders =
SUMMARIZE('Pos_Data',
'Pos_Data'[STORE_KEY],
'Pos_Data'[DATE_KEY],
'Pos_Data'[TRANSACTION_TYPE_KEY],
"DISTINCT_ORDER_NUMBERS",
DISTINCTCOUNT('Pos_Data'[TRANSACTION_NUM]))
RETURN SUM(_TotalOrders[DISTINCT_ORDER_NUMBERS])
Please assist
The SUM function expects a base table rather than a calculated table.
Try this instead:
VAR _TotalOrders =
SUMMARIZE('Pos_Data',
'Pos_Data'[STORE_KEY],
'Pos_Data'[DATE_KEY],
'Pos_Data'[TRANSACTION_TYPE_KEY],
"DISTINCT_ORDER_NUMBERS",
DISTINCTCOUNT('Pos_Data'[TRANSACTION_NUM]))
RETURN SUMX(_TotalOrders, [DISTINCT_CHECK_SEQ])
Edit: If the difference you mentioned is related to nulls, then try this in place of DISTINCTCOUNT.
COUNTAX( DISTINCT( 'Pos_Data'[TRANSACTION_NUM] ), 'Pos_Data'[TRANSACTION_NUM] )
The COUNTAX function (as opposed to COUNTX) does not count nulls.