I have a closing date and delivery date column, if the date difference greater than 1 then, I need to generate date series with a closing date column. I have attached the example closing date and delivery date details below.
I want the output to be like the below one
Please help me in solving this issue.
Using this extended table and the following code I believe you would get the desired results:
Closing | Delivery | Difference | Order
---------------------------------------
190228 | 190321 | 21 | A
190228 | 190301 | 1 | B
190310 | 190317 | 7 | C
ExpandedDeliveryTable =
SELECTCOLUMNS(
FILTER(
ADDCOLUMNS(
CROSSJOIN(
CALCULATETABLE(
'Deliveries';
'Deliveries'[Difference] > 1
);
GENERATESERIES(
0;
MAX('Deliveries'[Difference]);
1
)
);
"Filter";
IF( [Delivery]-[Closing] < [Value]; 1; BLANK() )
);
[Filter] <> 1
);
"Closing_Date"; [Closing]+[Value];
"DeliveryDate"; [Delivery];
"Date Diff"; [Value];
"Order"; [Order]
)
This generates a new table looking like this:
]
Related
I'm trying to calculate the daydiff between when the first (H1) and the second (H2) product have been bought for each customer (ID)
I can do it if the dates are on the same line, but not on mulitple rows. There are 5.6mil rows in all with 30 different products, but right now its only between H1 and H2
The result i'm after is something like
For a data source with 5.6M rows, I would only recommend doing it though native server-side query unless the calculations are not required to evaluate in respect to some filter context. Else, you can do it through the following DAX measure.
If you have a table like this and you want the DateDIff by ID for each preceding PurchaseDate
| ID | Product | PurchaseDate |
|----|---------|--------------|
| 10 | H1 | 2021-09-15 |
| 10 | H2 | 2021-09-19 |
| 20 | H1 | 2021-05-01 |
| 20 | H2 | 2021-06-05 |
| 20 | H3 | 2021-07-08 |
you can write the following measure
Measure =
VAR _curentlyVisibleDateById =
MAX ( 'fact'[PurchaseDate] )
VAR _immediatelyPrecedingDateById =
CALCULATE (
CALCULATE (
MAX ( 'fact'[PurchaseDate] ),
'fact'[PurchaseDate] < _curentlyVisibleDateById
),
ALLEXCEPT ( 'fact', 'fact'[ID] )
)
VAR _diffbyId =
DATEDIFF ( _immediatelyPrecedingDateById, _curentlyVisibleDateById, DAY )
RETURN
_diffbyId
Edit
If you want to limit calculations to only specific groups of Product; i.e. only for Products H1,H2,H3 then please use this
Measure =
VAR _curentlyVisibleDateById =
CALCULATE (
MAX ( 'fact'[PurchaseDate] ),
'fact'[Product] IN { "H1", "H2", "H3" }
)
VAR _immediatelyPrecedingDateById =
CALCULATE (
CALCULATE (
MAX ( 'fact'[PurchaseDate] ),
'fact'[PurchaseDate] < _curentlyVisibleDateById
),
ALLEXCEPT ( 'fact', 'fact'[ID] ),
'fact'[Product] IN { "H1", "H2", "H3" }
)
VAR _diffbyId =
DATEDIFF ( _immediatelyPrecedingDateById, _curentlyVisibleDateById, DAY )
RETURN
_diffbyId
I have 2 dimension tables with no relation between them.
1 is Product Dimension table as
ProdCode | ValidStartDate | ValidEndDate
XX | 2012-01-01| 2016-12-31
XX | 2017-01-01| 2017-12-31
XX | 2018-01-01| 2020-12-31
2nd is Time table
Year | IsCurrent
2012 | 0
2013 | 0
2014 | 0
2015 | 0
2016 | 0
2017 | 0
2018 | 0
2019 | 0
2020 | 1
I need to create a calculated column in Product table to show IsCurrent column from Time Table wrt the year selected.
I tried with CALCULATE but it expects one of the aggregate functions which i can not use because i want to show value in current row context.
for example:
IsCurrent =
CALCULATE(
MAXA('Time'[IsCurrent]),
FILTER(
'Time',
'Time'[Year] >= YEAR(Product[ValidStartDate])
&& 'Time'[Year] <= YEAR(Product[ValidEndDate])
)
)
This always gives me Max value from the range satisfied for example in case of 1st record (2012- 2016) shows 2016 always but I want to show respective current row year from Time table.
Please suggest.
Thank you.
Try this below Measure script-
Measure
IsCurrent =
CALCULATE(
MAXA('Time'[IsCurrent]),
FILTER(
'Time',
'Time'[Year] >= YEAR(MIN(Product[ValidStartDate]))
&& 'Time'[Year] <= YEAR(MIN(Product[ValidEndDate]))
)
)
Custom Column
IsCurrent_column =
var current_start_year = YEAR(Product[ValidStartDate])
var current_end_year = YEAR(Product[ValidEndDate])
RETURN
CALCULATE(
MAXA('time'[IsCurrent]),
FILTER(
'time',
'time'[Year] >= current_start_year
&& 'time'[Year] <= current_end_year
)
)
Here is the output-
Create this below measure-
in_range =
VAR selected_year = SELECTEDVALUE('time'[Year])
RETURN IF(
YEAR(MIN('product'[ValidStartDate])) <= selected_year
&& YEAR(MIN('product'[ValidEndDate])) >= selected_year
,
1,
0
)
This will give you a output as below-
Now you can add a Visual Level filter using this above measure so that the row wonly show when in_range = 1. This filter will only keep your expected rows in the table.
I have a Power BI report and I want to find the last date some action took place that had a non-0 value. In the following example:
|-------------|------------|
| ActionDate | ActionAmt|
|-------------|------------|
| 1-Feb | -100 |
|-------------|------------|
| 1-Feb | 100 |
|-------------|------------|
| 10-Jan | 150 |
|-------------|------------|
I want to return the 10-Jan date, not 1-Feb, since 10-Jan is the first non-0 value summed by ActionDay. My code returns 1-Feb:
Last Action Date =
VAR maxdatekey =
CALCULATE ( MAX ( 'Action'[ActionDateKey] ), 'Action'[ActionAmount] > 0 )
RETURN
IF (
maxdatekey,
FORMAT (
LOOKUPVALUE ( 'Date'[DateValue], 'Date'[DateKey], maxdatekey ),
"dd-MMM-yyyy"
)
)
How do I further group this to exclude the summarized 0 days?
I think you're looking for something like this where you summarize by date when calculating the amount:
LastActionDate =
VAR Summary =
SUMMARIZE (
'Date',
'Date'[DateValue],
"Amt", CALCULATE ( SUM ( 'Action'[ActionAmount] ) )
)
RETURN
FORMAT (
MAXX ( FILTER ( Summary, [Amt] > 0 ), 'Date'[DateValue] ),
"dd-MM-yyyy"
)
I'm working with PowerBI and have the following table:
customer_id|item_id| date
1 | A | 01/01/01
1 | B | 01/01/01
1 | A | 02/02/02
1 | A | 03/03/03
2 | A | 03/03/03
2 | C | 03/03/03
...
I would like to find the earliest date for each customer_id who purchased item A and return 1 in a new column. So that I get a new column in the table that looks like the following:
customer_id | item_id | date | Column_want
1 | A | 01/01/01 | 1
1 | B | 01/01/01 | blank
1 | A | 02/02/02 | blank
1 | A | 03/03/03 | blank
2 | A | 03/03/03 | 1
2 | C | 03/03/03 | blank
...
I've tried to filter the column by item A and then using TOPN(1,...) to choose only the top rows. However, it doesn't seem to work.
This seems like such a trivial request. Is there any smarter way around this?
It's possible to use TOPN for this but that function returns an entire row of a table so it looks pretty clunky like this:
Column_want =
IF (
Table1[item_id] = "A" && Table1[date]
= SELECTCOLUMNS (
TOPN (
1,
FILTER (
Table1,
Table1[item_id] = "A"
&& Table1[customer_id] = EARLIER ( Table1[customer_id] )
),
Table1[date], ASC
),
"date", Table1[date]
),
1
)
I'd suggest something more like this:
Column_Want =
IF (
Table1[date]
= CALCULATE (
MIN ( Table1[date] ),
FILTER (
ALLEXCEPT ( Table1, Table1[customer_id], Table1[item_id] ),
Table1[item_id] = "A"
)
),
1
)
Or this:
Column_Want =
IF (
Table1[date]
= MINX (
FILTER (
Table1,
EARLIER ( Table1[item_id] ) = "A"
&& Table1[customer_id] = EARLIER ( Table1[customer_id] )
),
Table1[date]
),
1
)
You could create a calculated column using variables:
Column_want =
VAR Customer_id ='Table'[customer_id]
VAR Earliest_date = CALCULATE(MIN('Table'[date]),
FILTER('Table','Table'[customer_id]=Customer_id))
VAR Earliest_item = CALCULATE(MIN('Table'[item_id]),
FILTER('Table','Table'[date]=Earliest_date),
FILTER('Table','Table'[customer_id]=Customer_id))
RETURN IF('Table'[date]=Earliest_date && 'Table'[item_id]=Earliest_item,
1,BLANK())
The idea is to calculate the earliest date for a particular Customer ID using Calculate and max (Earliest_date variable). Earliest_Item variable is calculated to avoid multiple records for the same customer getting tagged as 1. Hope this helps.
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.