Lookup based on minimum value by category - powerbi

I am trying to find the location with the large amount of shortage for tools across multiple locations, and then apply that in a new column or measure so that any location I look at, I can see who has the biggest shortage and recommend to a garage with overage to ship to that location.
I have a data set with Tool Number, Locations, Overage/Shortage
I am trying to add which location has the largest shortage, and I not managed to apply this as a measure or column.
Data Example:
Tool | Location | Overage/Shortage
X-001 | Miami | 10
X-001 | New York | -7
X-001 | Boston | -4
So my max shortage I can get is -7, but when I try to apply lookup using tool and over/short it gives me errors, and if I use the follow, it would return New York, but just for the row with New York
GarageWithShortage =
VAR SearchValue = CALCULATE(
MIN(ToolExchage[Overage / Shortage]),
FILTER(ToolExchage, ToolExchage[TOOL_NUMBER_FW] = EARLIER(ToolExchage[TOOL_NUMBER_FW]))
)
RETURN
IF(SearchValue = 0,
BLANK(),
CALCULATE (
SELECTEDVALUE (ToolExchage[Yard Name] ),
FILTER (
ALL(ToolExchage[Overage / Shortage]),
ToolExchage[Overage / Shortage] == SearchValue
),
ALL ( ToolExchage[Yard Name] )
)
)

Please try this,
Measure 1,
Garage with shortage = CALCULATE(MIN('Table'[Shortage]), ALLEXCEPT('Table','Table'[Tool]))
Column 1,
MCheck = IF([Garage with shortage]='Table'[Shortage], "Yes", "No")
Screenshot,
https://i.stack.imgur.com/efGeC.png

Related

QoQ changes by Customer in DAX

I would like to create a DAX formula to calculate the increases and decreases of customers across periods. Following is a sample of the data that I have
Year-Quarter|Customer|Credit-Limit
2019Q2|A|50
2019Q2|B|100
2019Q2|C|100
2019Q2|D|200
2019Q2|E|1000
2019Q2|F|200
2019Q3|A|50
2019Q3|B|200
2019Q3|C|100
2019Q3|D|50
2019Q3|E|500
2019Q3|F|300
I am looking to create a summary by Year-Quarter showing the number of customers that had an increase/decrease/none of their Credit-Limit.
Note that this is just a sample and the actual data is >10M rows. So even though I can create another table, I think from a computation standpoint, a measure would be more useful
Desired Output:
A commentary like the following: "There are 2 customers that have increased credit limit in 2019Q3"
Done so far:
Prev Quarter Credit Limit =
VAR CurrentYearQuarter = MAX(Sheet1[Year-Quarter])
VAR Quarter_Year =
LEFT (CurrentYearQuarter, 4)
VAR Quarter_period =
RIGHT (CurrentYearQuarter, 1 )
RETURN
IF (
Quarter_period = "1",
CALCULATE (
SUM ( Sheet1[Credit Limit] ),
Sheet1[Year-Quarter]
= ( Quarter_Year - 1 )
& "Q"
& ( Quarter_period + 3 )
),
CALCULATE (
SUM ( Sheet1[Credit Limit] ),
Sheet1[Year-Quarter]
= Quarter_Year
& "Q"
& Quarter_period - 1
)
)
Inc/Dec = IF(SUM(Sheet1[Credit Limit]) - [Prev Quarter Credit Limit] > 0,"Inc",
IF(SUM(Sheet1[Credit Limit]) - [Prev Quarter Credit Limit] < 0,"Dec","None"))
Commentary = "There are " &
CALCULATE(DISTINCTCOUNT(Sheet1[Customer]),
FILTER(Sheet1, [Inc/Dec] = "Inc" && Sheet1[Year-Quarter] = "2019Q3"))
Current output:
Commentary: "There are 4"
I am not sure why I am getting 4 as compared to 2 as the number here. Help or guidance would be really appreciated
I've slightly altered the input data for experimental purpose, I've added
2018Q3 | A | 200
2018Q4 | A | 50
2019Q1 | A | 50
I've added a Quarter-Calendar (which is a calculated table using VALUES(Sheet1[Year-Quarter])
Then by adding more columns to this new table, extracting the current year and quarter using LEFT and RIGHT, then calculating the previous quarter, previous year and combining to a Prevoius-Year-Quarter column:
]
Using this Q-Calendar I create a 1:* relationship to the Sheet1 table between [Year-Quarter] and [Year-Quarter], then I create a second inactive 1:* relationship between [Previous-Year-Quarter] and [Year-Quarter] like this:
I then create two measures, one for sum of previous quarter credit an one for current quarter credit:
Current-Quater CL =
var currentQ = MAX('Q-Calendar'[Year-Quarter])
var tempTable =
FILTER(
ALL('Q-Calendar');
'Q-Calendar'[Year-Quarter] = currentQ
)
return
CALCULATE(
SUM('Sheet1'[Credit-Limit ]);
tempTable
)
In the [Previous-Quarter CL] measure I use USERELATIONSHIP to activate the passive relationship I added from the Q-Calendar.
Prev-Quater CL =
var currentQ = MAX('Q-Calendar'[Year-Quarter])
var tempTable =
FILTER(
ALL('Q-Calendar');
'Q-Calendar'[Year-Quarter] = currentQ
)
return
CALCULATE(
SUM('Sheet1'[Credit-Limit ]);
tempTable;
USERELATIONSHIP('Sheet1'[Year-Quarter]; 'Q-Calendar'[Previous-Year-Quarter])
)
Then create the Inc/Dec measure like this:
Increase/Decrease =
var temp = [Current-Quater CL]-[Prev-Quater CL]
return
SWITCH(
TRUE();
temp > 0; "Increase";
temp < 0; "Decrease";
"No change"
)
And finally created a new (actually 3 new) Commentary measures like this:
Commentary_2 = "There are " &
var customers = VALUES(Sheet1[Customer])
return
SUMX(
customers;
CALCULATE(
IF(
[Current-Quater CL]-[Prev-Quater CL] > 0;
1;
0
)
)
)&" customers how have increased their credit"
Using the Year-Quarter column from the Q-calendar as a slicer I get the current status and I can select a previous quarter to see the status at that time:
N.B: The code in my measures can be optimised, I just kept them as detailed as this to make it more understandable.

In Power BI - count and sum instances in transactional database where item A is more frequent than item B

I have a transactional table that looks like data that would flow in from a point of sale. Using DAX/Power BI, I want to be able to count and sum the instances where Item A is more frequent on the invoice than Item B.
I'm having a hard time pasting my data but imagine a transactional dataset with 3 Columns: Invoice Number, Qty sold, Product
Invoice | Qty sold | Product
---------------------------------
1111 | 5 | Apples
1111 | 6 | Bananas
1111 | 6 | Oranges
1112 | 10 | Apples
1112 | 5 | Bananas
1112 | 3 | Oranges
1112 | 3 | Strawberries
And I want to be able to see it every combination of products above and how frequently 1 has a greater sales quantity than the other:
Apples > Apples: 0
Apples > Bananas: 1
Apples > Oranges: 2
Apples > Strawberries: 1
Bananas > Bananas: 0
Bananas > Apples: 1
Bananas > Oranges: 2
etc
I have tried duplicating the table and doing a many to many join on invoice. From there, count rows from table 1 where count > than table 2 using the "related" and "related table" functions (this is how I would do it in SQL). This hasn't worked due to the many to many nature. I have also tried something like this but it is not providing the desired output:
MoreFreq =
CALCULATE(
COUNT(Fact2[Qty Sold]),
FILTER(
Fact2,
Fact2[Qty Sold] > Fact1[Qty Sold]
)
)
Any help would be appreciated. Thanks!
Since you only provided a single table, not really sure how you plan to display it visually, with more Dimensions to provide selection you will be able to do something more flexible.
You could create a Calculated Table:
Table =
ADDCOLUMNS(
DISTINCT(GENERATE(VALUES(Fact2[Product]);SELECTCOLUMNS(VALUES(Fact2[Product]);"Product2";[Product])));
"Count";
COUNTX(VALUES(Fact2[Invoice]);
VAR p1 = [Product]
VAR p2 = [Product2]
VAR p1c = CALCULATE(SUM(Fact2[Qty]);p1=Fact2[Product])
VAR p2c = CALCULATE(SUM(Fact2[Qty]);p2=Fact2[Product])
RETURN
IF(p1c>0 && p2c>0 && p1c>p2c;1)
)
)
I took a crack at it, most of the complexity stems from the fact that you want to add the product combination (e.g. "Apples > Bananas") to visual in Power BI. In order to do this it needs to be a physical column in your data model. That eliminates create a single measure. I chose to use a calculated table. In this table I calculate all the product combinations and their related quantity per invoice and add a new display column "product combination":
Crossjoin =
FILTER (
ADDCOLUMNS (
CROSSJOIN (
'Table',
SELECTCOLUMNS ( VALUES('Table'[Product]), "ProductName", 'Table'[Product] )
),
"RelatedQty", CALCULATE (
SUM ( 'Table'[Qty sold] ),
FILTER (
ALLEXCEPT ( 'Table', 'Table'[Invoice] ),
'Table'[Product] = EARLIER ( [ProductName] )
)
),
"Product Combination", 'Table'[Product] & " > " & [ProductName]
),
'Table'[Product] <> [ProductName]
&& [RelatedQty] > 0
)
After that the measure to calculate the instances where a product is sold more than another is pretty straightforward:
Measure =
SUMX (
'Crossjoin',
IF ( 'Crossjoin'[Qty sold] > 'Crossjoin'[RelatedQty], 1, 0 )
)
An alternative solution could be to generate all the "Product Combinations" possible from the data at Data Load as a new table and do the crossjoin inside the measure. I chose the calculated table to make the calculations more visible.
Hope that helps!
Jan
You can do this with two copies of a product dimension, and no relationships to the fact table.
'Fact' is as you shared in your original post.
'Dim1' and 'Dim2' are each a distinct list of all products.
Expected usage is that you put 'Dim1'[Product1] and 'Dim2'[Product2] onto a table or matrix visual. For matrix, you could do one on rows and one on columns.
// base measure
Quantity = SUM ( 'Fact'[Qty Sold] )
// the measure you want
Dim1 > Dim2 =
// Count the rows defined by the FILTER table expression.
// This will be a count of distinct invoices, based on a
// filter predicate.
COUNTROWS (
// Iterate invoices, keeping only those that have Dim1 > Dim2
FILTER (
VALUES ( 'Fact'[Invoice] ),
// Fore each invoice, calculate Dim1Qty and Dim2Qty
VAR Dim1Qty =
CALCULATE (
[Quantity],
TREATAS ( VALUES ( 'Dim1'[Product1] ), 'Fact'[Product] )
)
VAR Dim2Qty =
CALCULATE (
[Quantity],
TREATAS ( VALUES ( 'Dim2'[Product2] ), 'Fact'[Product] )
)
RETURN
// Keep only invoices where this predicate is true
Dim1Qty > Dim2Qty
)
)

DAX conditional sum of two columns with different granularity

This is follow up question of the one asked here. However this time two columns have different granularity and are located in different tables. So simple SUMX solution proposed earlier is not applicable. I attach SumDifferntGranularity.pbix file.
How to construct a DAX measure which returns sum of either BudgetProduct (if possible) or BudgetBrand. The logic is take Brand if Product is empty. So expected results looks like this:
+---------+-------------+---------------+-----------------+
| Manager | BudgetBrand | BudgetProduct | Expected result |
+---------+-------------+---------------+-----------------+
| Alice | 16 | 15 | 15 |
| John | 7 | | 7 |
| Martha | 21 | 21 | 21 |
| Zadar | 11 | | 11 |
+---------+-------------+---------------+-----------------+
| Total | 55 | 36 | 54 |
+---------+-------------+---------------+-----------------+
In this example, all Managers have budget defined on Brand, but some Managers (Alice and Martha) have budget defined on Products. How to construct a measure which will take budget defined on products, if possible, but if not possible then it will take the budget defined on Brands.
I think this will work:
Expected Result =
VAR Summary =
SUMMARIZE (
Unique_Manager,
Unique_Manager[Manager],
"Budget_Brand", SUM ( Budget_Brand[BudgetBrand] ),
"Budget_Product", SUM ( Budget_Product[BudgetProduct] )
)
RETURN
SUMX (
Summary,
IF ( ISBLANK ( [Budget_Product] ), [Budget_Brand], [Budget_Product] )
)
This groups by Manager and calculates a summary table with the sum for BudgetBrand and BudgetProduct for each and the iterates through this summary table with SUMX using the logic specified.
Here's a bit cleaner implementation
Expected Result =
SUMX (
VALUES ( Unique_Manager[Manager] ),
VAR SumBrand = CALCULATE ( SUM ( Budget_Brand[BudgetBrand] ) )
VAR SumProduct = CALCULATE ( SUM ( Budget_Product[BudgetProduct] ) )
RETURN
IF ( ISBLANK ( SumProduct ), SumBrand, SumProduct )
)
I this one, we don't need a calculated table to iterate over. Instead, we iterated over all the distinct values of Manager in the local filter context and sum BudgetBrand and BudgetProduct within that context. Note that I've wrapped the sums in CALCULATE. This is done to perform the context transition from the row context inside SUMX (the particular Manager) to having that Manager as a filter context on BudgetBrand and BudgetProduct. Storing these sums as variables makes for a more readable IF line and only requres SumProduct to be computed once instead of twice.

Determining a Style Changeover by Machine using PowerBI

So I have a table that has the output of all machines in a department with styles. For example:
|Machine| |Style| | QTY| |Time| |Date| etc...
1 001 100 8:00AM 5/21/19
2 001 200 8:05AM 5/21/19
1 001 100 9:00AM 5/21/19
1 004 100 10:00AM 5/21/19
2 001 200 9:05AM 5/21/19
I'm looking to see the amount of times a style is changed for a machine. So in this case, for Machine 1 it was one style change and for Machine 2 it was zero.
I've tried adapting some code to no avail; mainly because I'm having trouble understanding the logic and I can't really think of a good index to work with.
Here is what I got so far:
EarliestChange Over Index =
VAR Temp =
CALCULATE (
MAX ( Table[Index] ),
FILTER (
Table,
[Index] < EARLIER ( [Index] )
&& [Style] <> EARLIER ( [Style])
&& Table[Date] = today()-1
)
)
VAR Temp1 =
CALCULATE (
MIN ( [Index] ),
FILTER (
Table,
[Index] > EARLIER ( [Index] )
&& [Style] <> EARLIER ( [Style])
&& Table[Date] = today()-1
)
)
RETURN
IF ( [Index] > temp && OR ( [Index] < temp1, ISBLANK ( temp1 ) ), temp + 1, 0 )
I tried to restrict it to just one day so that I could evaluate the results so that portion can be dropped. I've tried two different indexes, one was the machine number and the other was the difference in time from today and the min date on the table. In a visual, I've been taking a distinct count of the EarliestChange Over Index and subtracted one since it didn't constitute a "change over."
EDIT:
Issue where multiple styles are logged at the same time causing false change overs.
|Machine| |Style| | QTY| |Time| |Date| etc...
1 001 100 8:00AM 5/21/19
1 001 100 9:00AM 5/21/19
1 004 100 10:00AM 5/21/19
1 004 100 10:00AM 5/21/19
1 004 100 10:00AM 5/21/19
In one department a time would never be duplicated. However, in another department (for whatever reason) might log 3 rolls at the same time. This would cause the equation to log 10:00am as 3 change overs. It might be a system glitch why there isn't unique time stamps per roll but this is the case unfortunately.
One way of doing it:
First, I modified your data as follows:
Added a record for Machine 1 at 11:00AM to capture a situation when a style reverts to the old one;
Added a column for Date-Time (simply Date + Time), to make life easier;
Named the table as "Data"
Measure:
Style Change Count
=
SUMX (
Data,
VAR Current_DateTime = Data[Date-Time]
VAR Current_Style = Data[Style]
VAR Previous_DateTime =
CALCULATE (
MAX ( Data[Date-Time] ),
FILTER ( ALLEXCEPT ( Data, Data[Machine] ), Data[Date-Time] < Current_DateTime )
)
VAR Previous_Style =
CALCULATE (
VALUES ( Data[Style] ),
FILTER ( ALLEXCEPT ( Data, Data[Machine] ), Data[Date-Time] = Previous_DateTime )
)
RETURN
IF ( Current_Style = Previous_Style || ISBLANK ( Previous_Style ), 0, 1 )
)
Result:
How it works:
We need to use SUMX to make sure that our subtotals and totals are correct;
SUMX iterates over Data table and for each record computes "Previous date-time", which is simply the max datetime less than the current datatime, per machine (hence ALLEXCEPT);
Then, we can calculate Previous Style, which is a style where date-time = previous date-time;
Finally, we compare current style and previous style. If they are not the same, we add 1;
In addition, I added a test for the starting condition - first occurrence of a machine, for which previous style does not exist yet. I did not treat such records as "style change". If you want to count initial records as style change, remove ISBLANK() part.

Unable to calculate percent of column total in power bi

I am trying to create a simple measure that represents a countries sales as a percentage of total sales. I first created a Slicer on the page so the user can filter to a specific country. I then wanted to use the sales of the filtered country as the numerator, and for the denominator using the ALL function remove all filters so it sums the grand total. The idea is I would then represent the data for each store (rows) to see how that store performs
However, when I do this all I see is 100% for every row when I run the report.
How can I make sure the numerator and denominator correctly understand the context / filters when doing their calculation.
Test Performance Variance =
VAR __BASELINE_VALUE = SUM('Test'[Sales])
VAR __VALUE_TO_COMPARE = SUM('Test'[Sales])
RETURN
IF(
NOT ISBLANK(__VALUE_TO_COMPARE),
DIVIDE(__VALUE_TO_COMPARE,
CALCULATE( __BASELINE_VALUE,ALL(Test[Country])))
)
Desired result is this:
Store | Sales | Performance
ABC | 15 | 15%
DEF | 65 | 65%
GHI | 20 | 20%
But instead I am seeing:
Store | Sales | Performance
ABC | 15 | 100%
DEF | 65 | 100%
GHI | 20 | 100%
You are putting a constant (the VAR you defined) within a CALCULATE, so the ALL doesn't do anything because a constant is fixed and doesn't change with the filter context.
Try rewriting the measure like this:
Test Performance Variance =
VAR __BASELINE_VALUE = CALCULATE ( SUM ( 'Test'[Sales] ), ALL ( Test[Country] ) )
VAR __VALUE_TO_COMPARE = SUM ( 'Test'[Sales] )
RETURN
IF (
NOT ISBLANK ( __VALUE_TO_COMPARE ),
DIVIDE ( __VALUE_TO_COMPARE, __BASELINE_VALUE )
)