DAX - sum column based on multiple containsstring - powerbi

Using the table attached as an example 'Financial_Tab'.
I want to sum [Budget] based on whether "1.2.4" is within [CBS Code], and where "NOP1" or "NOP2" or "NOP3" is within [CBS Name]. Returning £50 in the example table.
I'm struggling looking for a succinct and functional way of searching for NOP1/NOP2/NOP3 in one go. I'm returning blank results. I think IN {} could be used but I cant get it to work with containsstring.
I really appreciate any help.
Thanks

This is what you're looking for:
Sum Budget =
CALCULATE(
SUM('Table'[Budget]),
CONTAINSSTRING('Table'[CBS Code], "1.2.4"),
CONTAINSSTRING('Table'[CBS Name], "NOP1")
|| CONTAINSSTRING('Table'[CBS Name], "NOP2")
|| CONTAINSSTRING('Table'[CBS Name], "NOP3")
)

Related

DAX Flag in Matrix Visual - Multiple levels of analysis

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()
)

Returning the first result of an table

I'm struggling within DAX to find a formula to return the first result. My table is as folllows:
The unique column is Dim_B_ID. So what I really would like to have is to return the first result of Amount ONLY for Dim_B_ID where the column IN is not blank. Im struggling cause I get answers like 3500 (total of the rows) and I can't seem to integrate IF(NOT(ISBLANK( funtion into this. So if someone has a solution for me, I would really appreciate it as I'm not so much of an expert in DAX.
You could try using the following measure:
FirstNonBlank =
FIRSTNONBLANKVALUE(
'Table'[Dim_Date_ID],
SUM( 'Table'[IN] )
)
When put together with Dim_B_ID in a table for example you could visualize FirstNonBlank for every "categorie" like so:
Used slightly modified sample data here:

Why using ALLSELECTED() AND FILTER() together?

I am trying to understand the below DAX code:
CALCULATE(
SUM(Revenue[Net])
,FILTER('Center', NOT 'Center'[Acc] IN {"RSM", BLANK() })
,ALLSELECTED()
,VALUES('Customer'[Customer Number])
)
I have the below questions:
What's the use of ALLSELECTED?? By definition ALLSELECTED returns all rows in a table, ignoring any filters that might have been applied inside the query, but keeping filters that come from outside. https://dax.guide/allselected/
So, what's the point of writing FILTER() if its going to be forced to be ignored by the next line (ALLSELECTED)?!?
Also by definition:
CALCULATE is just a expresion followed by filters...
What's the use of VALUES() ? It doesn't appear to be a filter, so how is it even allowed to appear there? (Per definition VALUES(): returns a one-column table that contains the distinct values from the specified column.)
I do not understand what is this returning? is it the SUM() or the VALUES()?
(I come from a SQL background, so any sql-friendly answer is appreciated).
In Dax every filter is a table of values its look similar to INNER JOIN;
ALLSELECTED is useful when you need to keep a row context (this is also a filter in DAX). You can use ALLSELECTED inside FILTER function.
For better understand what engine does you can use a DaxStudio with ServerTiming;
As you see this product one simple statement:
SELECT
SUM ( 'Table'[Cost Centre] )
FROM 'Table'
WHERE
'Table'[Project] NIN ( 'AB' ) ;
You can find useful article by Alberto Ferrari and Marco Russo:
https://www.sqlbi.com/tv/auto-exist-on-clusters-or-numbers-unplugged-22/
If it is only converting DAX queries if your connecting your sql analysis services to in DAX studio. because it is not working for PBI file data

Power BI why circular dependency is detected

Can you please explain why I run into this alert message of circular dependency when I try to create relationship between dimension #product (or #region) and a #bridge table which is a Cartesian of product x region?
I have connected #bridge with Sales and Budget by single column P#G witch is concatenation of product and region.
Download file here: PBIX
The solution is simple. Do not use CALCULATE function in the DAX bridge tables. Instead add all that columns to the same table later as calculated columns.
I changed the original code of the bridge table which was:
ADDCOLUMNS (
CROSSJOIN ( '#product', '#region' ),
"P#R", COMBINEVALUES("#",'#product'[product], '#region'[region]),
"sales", CALCULATE ( SUM ( Budget[target] ) ),
"IsSale", IF ( CALCULATE ( SUM ( Budget[target] ) ) > 0, "Yes", "No" )
)
To something simpler:
ADDCOLUMNS (
CROSSJOIN ( '#prodact', '#region' ),
"P#R", COMBINEVALUES("#",'#prodact'[product], '#region'[region])
)
I modified the DAX code of bridge table so as to leaving only the columns necessary for joins. The columns that I needed to be calculated I added as calculated columns. And that's it. It was by pure chance I found that out while experimenting with it.
For playing with bridge tables I recommend this Alberto Ferrari's article: https://www.sqlbi.com/articles/avoiding-circular-dependency-errors-in-dax/. It inspired me to solve the problem. What I get from the Alberto's text is that the functions VALUES and ALL are no good for bridge tables. He mentions issue of using CALCULATE function inside the bridge DAX tables. The function somehow is translated to mixture of ALL and FILTER functions. Instead of VALUE and ALL, use functions as DINSTINCT and ALLNOBLANKROW.
Working PBIX file. Hurray!
A quick and dirty solution is to creat to new versions of #product and #region by using VALUES. This is probably not the best way of doing it...
NewProduct = VALUES('#product'[product])
This new tables can be linked to #bridge with a 1:* relationship and thus can be used as a slicer on the dashboard.
Alberto has written about this on the sqlbi blog: Circular dependency sqlbi blog

PowerBI DAX - Identifying first instance based on multiple criteria

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