I have a situation below (Power BI - DAX) in which I am trying to SUMMARIZE a table called Product with a SUM aggregation to get the total cost of all products in each Category; but then I have to change the column name of one or two columns in the summarized result set.
I have written the below code to develop a calculated table:
ProductCategoryCostCT = SELECTCOLUMNS (
SUMMARIZE(
Product,
Product[Category],
"TotalCostOfAllProductsInThisCategory", SUM(Product[ProductCost])
),
"CategoryName", Product[Category],
"Cost", Product[TotalCostOfAllProductsInThisCategory]
)
The above code throws an error. Can someone help me correct this ? This may be pedestrian to many of you!
(The source Product table has ProductCost column at the individual Product level, with Category as another column
in the same table)
ProductCategoryCostCT = SUMMARIZE(
SELECTCOLUMNS(
Product,
"CategoryName", Product[Category],
"ProductCost", Product[ProductCost]
),
[CategoryName],
"Cost", SUM(Product[ProductCost])
)
Related
I am trying to join 2 tables (left join) in Power BI using DAX, and I keep on encountering errors.
The dummy table structure and desired outcome are below:
How would I join the two tables where the Application and Business Unit should match in Both Tables and considering that Table A & B contain duplicate values?
One of the statements I have tried is below, however I keep on encountering errors regarding duplicate values and I am not sure how to proceed. I can't use Power Query unfortunately, this has to be in DAX.
TABLE =
GENERATEALL (
Table_A,
CALCULATETABLE (
ROW (
"New vs Old", VALUES (Table_B[New vs Old]),
"Project", VALUES (Table_B[Project])
),
TREATAS ( ROW ( "Business Unit", Table_A[Business Unit] ), Table_B[Business Unit] ),
TREATAS ( ROW ( "Application", Table_A[Application] ), Table_B[Application] )
)
)
Thank you
Use NATURALLEFTOUTERJOIN Like this:
Table =
var TABLE_A = SELECTCOLUMNS(
{
("A","BU1","2022-10",100),
("B","BU2","2022-11",200),
("B","BU3","2022-10",100),
("C","BU1","2022-11",400),
("D","BU2","2022-12",50)
},"Application",[Value1],"Business Unit",[Value2], "Month",[Value3], "Cost",[Value4])
var TABLE_B = SELECTCOLUMNS(
{
("A","BU1","Project 1","New"),
("B","BU2","Project 2","New"),
("B","BU2","Project 5","Old"),
("B","BU3","Project 3","Old"),
("C","BU1","Project 1","Old"),
("D","BU2","Project 4","New")
},"Application",[Value1],"Business Unit",[Value2], "Project",[Value3], "New vs Old",[Value4])
return NATURALLEFTOUTERJOIN(TABLE_A,TABLE_B)
If your column names or data types don't match you'll need to CONVERT and rename them before joining.
You need to create a Calculated Column that introduces a Union between "Applications" and "Business Unit", in both tables, then introduce tge relationship with this column created. It’s like creating a Primary Key.
So, I have the following tables in my Power BI :
Sales : Date | ID_Client | ID_Product | Amount
Client : ID_Client | Name_Client
I would like to get the number of unique BIG clients in any given month. I therefore use the following formula (which I then put in a column in a table with months in rows):
# BIG Clients =
VAR threshold = 10000
RETURN
(
CALCULATE(
DISTINCTCOUNT( Sales[ID_Client] ),
FILTER(
SUMMARIZE(
Sales,
Sales[ID_Client],
"Sales", SUM( Sales[Amount] )
),
[Sales] >= threshold
)
)
)
QUESTION IS : how can I get the list of those BIG clients for any given month? Let's say I click on the November number of big clients in my table, could another table nearby display the list of those clients ?
Thanks in advance for your kind help, I've been trying for a while :)
I assume that you have a table of clients with the Name column with a one to many relationship with the Sales table and that you do not have duplicate client names. Then you may create a [BIG Sales] measure to be used in a table or matrix visual with client names on the rows.
since [BIG Sales] evaluates to BLANK() for clients with less that threshold sales, they are automatically filtered out from the visual
BIG Sales =
VAR threshold = 10000
VAR BigCustomers =
FILTER(
ADDCOLUMNS(
VALUES( Clients[Name] ),
"Sales", SUM( Sales[Amount] )
),
[Sales] >= threshold
)
RETURN
SUMX(
BigCustomers,
[Sales]
)
You could create a table or matrix visual with the client on the rows and use your measure in the values field. This will show 1 for all big clients and return blank for the rest (which should hide them). If you don't want to show the measure, you can set the value is 1 in the filter pane and remove the measure from the values field.
A more direct option is to use a simple SalesAmount = SUM ( Sales[Amount] ) measure in the values field and filter like this
I face difficulties with applying the RANKX function.
The ranking in the example below should be dynamically modified by Customer in the Matrix Rows, Year in the Matrix Columns and Group, Year and Week in the slicers. The ranking is based on the Volume measure shown herebelow.
Issue:
When all weeks are selected the ranking works fine, but whenever I filter on certain weeks the ranking shows double ranks. How can I solve this?
The DAX I used:
Rank =
RANKX( ALL(Volume[Customer]), Volume[Volume],,DESC, Dense)
Volume = SUM(Volume[Total Volume])
Screenshots of the matrix
1. Matrix when all weeks are selected, showing the right ranks
2. Matrix when certain weeks are selected, showing wrong ranks
Can you try with this below code-
Rank =
RANKX(
ALLSELECTED(Volume[Customer]),
Volume[Volume],
,
DESC,
)
Since we have a single table instead of a star schema there are cross-filtering effects. To remove these we must first remove the whole filtering, then apply back the desired filters from the visual and from the slicers.
Rank 1 =
VAR Customers =
ALLSELECTED( Volume[Customer] )
VAR Result =
CALCULATE(
RANKX( Customers, Volume[Volume],, DESC, DENSE ),
REMOVEFILTERS( Volume ),
VALUES( Volume[Year] ),
VALUES( Volume[Customer] ),
ALLSELECTED( Volume[Week] )
)
RETURN
Result
Since there are no slicers on Customer, we might also use ALL instead of ALLSELECTED
How to filter all products on promotion? Say we have two tables Sales and Budget without physical relationship. Here model is simplified and let's assume that it is the case, we cannot create physical relationship. We have to use virtual relationship.
We can see summary:
The two first columns are of the Sales table. The third column BudgetTreats is a measure:
BudgetTreatas =
CALCULATE (
SUM ( Budget[amount] ),
TREATAS (
VALUES ( Sales[id] ),
Budget[id]
)
)
Now I would like to resolve two things:
How to make a slicer to filter out only the products (id) which have BudgetTreatas?
How to create a measure for calculating sales but only for products which have a budget? So analogous measure as BudgetTreatas presented above.
And of course sample data: DAX TREATS.pbix
I posted an answer to my question but it is not to show an answer but rather to show working solutions, and give you idea on expected results. I would be grateful for any answer or comments.
References:
The Logic behind the Magic of DAX Cross Table Filtering
Virtual Filters Using TREATAS
How To Use The TREATAS Function - Power BI & DAX
Creating Virtual Relationships Using TREATAS - Advanced Power BI Technique
Measure calculating Sales filtered by ids in Budget table.
Surprisingly this is not working:
//not working:
SalesFilteredByBudget1 =
CALCULATE (
[Sales],
TREATAS ( VALUES ( Budget[id] ), Sales[id] )
)
It seems we need an extra table. If we add to the model a Bridge table with all sales id and connect it to Sales table on id (without connecting it to Budget table!) we may resolve the issue.
//works:
SalesFilteredByBudget2 =
CALCULATE (
[Sales],
TREATAS ( VALUES ( Budget[id] ), Bridge[id] )
)
So it seems filters propagate further from tables used in TREATAS( VALUES on the tables connected by physical relations.
If we want to make a measure without Bridge table we can make extra table as a table variable.
// works:
SalesFilteredByBudget3 =
VAR Lineage =
TREATAS ( VALUES ( Budget[id] ), Sales[id] )
VAR tbl =
CALCULATETABLE ( Sales, KEEPFILTERS ( Lineage ) )
VAR result =
CALCULATE ( SUMX ( tbl, [amount] ) )
RETURN
result
I having trouble calculating the cumulative sum of a column on PowerBI.
I have a big offer table and I want to run a pareto analysis on it. Following many tutorials, I created a SUMMARIZED table by offer and a sum of their sales. So the table definition is:
summary = SUMMARIZE(big_table; big_table[offer]; "offer sales"; sum(big_table[sales]))
Many of the forums and stackoverflow answers I found have direct me to the following formula for cumulative sum on column:
cum_sales =
CALCULATE(
sum([offer_sales]);
FILTER(
ALLSELECTED(summary);
summary[offer_sales] <= max( summary[offer_sales])
)
)
However the resulting table is not correct:
What I need is simply to have the offers ordered by sales descending and then add the current row's sales amount to the previous row's sales,
So I excepted numbers closer to:
1st row: 1.5M
2nd row: 2.1M
3rd row: 2.6M and so on
But (maybe) because of my data structure and (certainly) lack of knowledge on how PowerBI works, I'm not getting the right results...
Total Amount = SUM ( 'Fact'[Amount] )
Offer Visual Cumulative =
VAR OfferSum =
ADDCOLUMNS (
ALLSELECTED ( 'Offer'[Offer] ),
"amt", [Total Amount]
)
VAR CurrentOfferAmount = [Total Amount]
VAR OffersLessThanCurrent =
FILTER (
OfferSum,
[amt] <= CurrentOfferAmount
)
RETURN
SUMX (
OffersLessThanCurrent,
[amt]
)
There's no need to pre-aggregate to a summary table. We can handle that as in the measure above.
This assumes a single fact table named 'Fact', and a table of distinct offers, 'Offer'.
Depending on what you're doing in terms of other filters on 'Offer', you may need to instead do as below:
Offer Visual Cumulative =
VAR OfferSum =
ADDCOLUMNS (
ALLSELECTED ( 'Offer'[Offer] ),
"amt", CALCULATE ( [Total Amount], ALLEXCEPT ( 'Offer', 'Offer'[Offer] ) )
)
...
The rest of the measure would be the same.
The measure is fairly self-documenting in its VARs. The first VAR, OfferSum is a table with columns ('Offer'[Offer], [amt]). This will include all offers displayed in the current visual. CurrentOfferAmount is the amount for the offer on the current row/axis label of the visual. OffersLessThanCurrent takes OfferSum and filters it. Finally, we iterate OffersLessThanCurrent and add up the amounts.
Here's a sample: