How is measure able to filter dimension via fact table? - powerbi

I have 2 tables: dimProduct and factSales
Dim table has productid, name, category
Fact table has salesid, productid, status, amount, paiddate
I have a table visual that shows the status from the fact table. Against each status I want to show the count of products and the count of distinct category.
CountProducts=DISTINCTCOUNT(FACTSALES[PRODUCTID])
CountDistinctCategory=DISTINCTCOUNT(dimProduct[category])
How to correct this?

Set the cross-filter direction for your relationship to 'Both', so that filtering can also propagate from the fact table to the dimension table.
Alternatively, using DAX:
CountDistinctCategory =
CALCULATE(
DISTINCTCOUNT( dimProduct[category] ),
TREATAS(
VALUES( factSales[productid] ),
dimProduct[productid]
)
)

Related

Left Joining Tables in Power BI based on multiple columns with duplicate values (DAX)

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.

DAX language- Microsoft Power BI - SUMMARIZE inside SELECTCOLUMNS - simple syntax

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

Sumx and Relatedtable in Power BI

I would like display the Product Current Cost measure for each Store_id in each Store_city in a matrix table using Power BI.
Here is my DAX:
Product current cost (test) =
CALCULATE(
SUMX(
'Product Lookup',
'Product Lookup'[current_cost]
),
RELATEDTABLE(
'Store Lookup'
)
)
Output:
Field pane:
The Product Lookup table does not have relationship with Store Lookup and Sales by store tables. Thus, I am using RELATEDTABLE function.
I am expecting the current cost (from Product Lookup table) value should not be the same for each store_city in each store_id.
Anything wrong in my DAX?
Updated:
Product Lookup:
Store Lookup:
You can acheive result by following measure
Product current cost (test) =
SUMX(
RELATEDTABLE('Store Lookup'), 'Product Lookup'[current_cost]
)

DAX Grouping Evaluation

In this measure - I'm creating a temp table to group by customer ID and return the year of the min order_date for each customer. I then want to count the # of customers that show up for a given year (basically just a row count).
What I'm struggling to understand is - this formula doesn't seem to look at the SUMMARIZE table within it. If I put year and this measure in a matrix, it counts based on the raw table, not the grouped version built by SUMMARIZE in the formula. Any ideas why it's evaluating this way?
COUNTROWS(
SUMMARIZE(
Orders,
Orders[Customer ID],
"min_order_date_year",
MIN(Orders[Order Date].[Year])))
The formula is OK as per logic you provided to it. You have to clear about both your requirement and what your are writing in your code. Your formula is returning exactly what you are instructing it.
If I understand correct, you simply need the Customer count for the Minimum Year. For say if you have 6 unique customer for Year 2019 and 11 unique customer for Year 2020, you are looking here for value 6 to return by your measure.
Now, what your summarize table actually returning? if you create a separate custom table for the Summarize code only as below, you can see the table will actually hold all your customer name/id in first column and the second column will hole the MIN year available for that customer.
orders_summarize =
SUMMARIZE(
Orders,
Orders[customer id],
"min_order_date_year",MIN(Orders[Order Date].[Year])
)
So basically you have list of all customer in your summarize table. And now your are counting rows of your summarize table which is actually returning the total number of unique customers.
Finally, if you wants customer count for a specific Year (like MIN year), follow these below steps-
Step-1: Create a custom summarized table as below-
store_summarized_table =
SUMMARIZE(
store,
store[Customer ID],
"mindate",MIN(store[Order Date])
)
Step-2: create a measure as-
count_cust_id = COUNT('store_summarized_table'[Customer ID])
Step-3: Now configure your Matrix visuals as shown in the below image. You can also get the output in the image-
To avoid the Physical Table, you can do this below-
Step-1: Create a Custom Column as below-
is_min_year =
// -- keep current row's customer id to a variable
VAR current_cust_id = store[Customer ID]
// -- keep current row's YEAR value to a variable
VAR current_year = store[Order Date].[Year]
// -- find the MIN YEAR from order date for the current row customer id
VAR min_year_current_custommer_id =
CALCULATE(
MIN(store[Order Date].[Year]),
FILTER(
store,
store[Customer ID] = current_cust_id
)
)
// -- check the current row's year is the MIN year of order date for the customer as well or not.
RETURN IF(current_year = min_year_current_custommer_id, 1,0)
OR create a measure as-
is_min_year_measure =
VAR min_order_year_for_current_customer =
CALCULATE(
MIN(store[Order Date].[Year]),
FILTER(
ALL(store),
store[Customer ID] = MIN(store[Customer ID])
)
)
RETURN
IF ( MIN(store[Order Date].[Year]) = min_order_year_for_current_customer, 1,0)
Step-2: Create a Measure as below-
For created Custom Column
count_cust_for_min_year =
CALCULATE(
DISTINCTCOUNT(store[Customer ID]),
FILTER(
store,
store[is_min_year] = 1
)
)
For Created Measure
count_cust_for_min_year =
CALCULATE(
DISTINCTCOUNT(store[Customer ID]),
FILTER(
store,
[is_min_year_measure] = 1
)
)
Now add "Order Date" and measure "count_cust_for_min_year" to your Matrix. The out put will same as below-

DAX TREATAS filtering by another table to get sales of all products on promotion

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