Hopefully a quick explanation of what I am hoping to accomplish followed by the approach we've been working on for over a year.
Desired Result
I have a table of SCD values with two columns, SCD_Valid_From and SCD_Valid_To. Is there a way to join a date table in my model (or simply use a slicer without a join) in order to be able to choose a specific date that is in between the two SCD columns and have that row of data returned?
Original Table
ID | SCD_Valid_From | SCR_Valid_To | Cost
1 2020-08-01 2020-08-03 5.00
Slicer date chosen is 2020-08-02. I would like this ID=1 record to be returned.
What We've Attempted So Far
We had a consultant come in and help us get Power BI launched last year. His solution was to create an expansion table that would contain a row for every ID/Date combination.
Expanded Original Table
ID | SCD_Valid_Date | Cost
1 2020-08-01 5.00
1 2020-08-02 5.00
1 2020-08-03 5.00
This was happening originally on the Power BI side, and we would use incremental refresh to control how much of this table was getting pushed each day. Long story short, this was extremely inefficient and made the refresh too slow to be effective - for 5 years' worth of data, we would need over 2000 rows per ID just to be able to select a dimensional record.
Is there a way to use a slicer where Power BI can select the records where that selected date falls between dates in two columns of a table?
Let me explain a workaround and I hope this will help you to solve your issue. Let me guess you have below 2 tables-
"Dates" table with column "Date" from where you are generating the date slicer.
"your_main_table" with with column "scd_valid_from" and "scd_valid_to".
Step-1: If you do not have relation between table "Dates" and "your_main_table", this is fine as other wise you have to create a new table like "Dates2". For this work around, you can not have relation between those tables.
In case you have already relation established between those tables, create a new custom table with this below code-
Dates2 =
SELECTCOLUMNS(
Dates,
"Date", Dates[Date]
)
From here, I will consider "Dates2" as source of your Date slicer. But if you have "Date" table with no relation with table "your_main_table", just consider "Dates" in place of "Dates2" in below measures creation. Now, Create these following 4 measures in your table "your_main_table"
1.
date_from_current_row = max(join_using_date_range[SCD_Valid_From])
2.
date_to_current_row = max(join_using_date_range[SCD_Valid_to])
3.
date_selected_in_slicer = SELECTEDVALUE(Dates2[Date])
4.
show_hide_row =
if(
[date_selected_in_slicer] >= [date_from_current_row]
&& [date_selected_in_slicer] <= [date_to_current_row]
,
1,
0
)
Now you have all instruments ready for play. Create your visual using columns from the table "your_main_table"
Final Step: Now just add a visual level filter with the measure "show_hide_row" and set value will show only when "show_hide_row = 1".
The final output will be something like below image-
Related
I am wondering is it possible to filter dim table based on fact table?
What I mean by that is that I have a dim table with records that are not all avalible in fact table. I load following dummy data to Power BI and create relationship by segment.
date
customer
segment
value
01.01.2021
1
A
10
02.01.2021
1
A
10
03.01.2021
1
A
10
04.01.2021
1
A
10
01.01.2021
2
B
20
02.01.2021
2
B
30
03.01.2021
2
B
40
dict table:
segment
segment_desc
A
Name of A
B
Name of B
C
Name of D
D
Name of D
Now I create one table with all column from facts and slicer with dim table.
As we see dim slicer shows all records from dim even if there are no coresponding records in fact table. I recall that for instance in QlikView we would only see records that are also in fact table. Is it possible in Power BI?
Enabling bi directional relationship doesn't do the trick - table is still not filtering the Slicer. I know that I can do inner join with fact table, but maybe there is a way to avoid this cumbersome solution.
This is one of the most annoying features of Power BI if you ask me. But there is a solution!
You need to write a new measure.
Dim Slicer Filter = INT( NOT ISEMPTY( 'fact table name' ) )
Next, make sure the dim slicer is selected, then drag and drop the new measure to the Filter pane. Drag the measure to one of the Filters on this visual boxes. In the options, make sure "is" is selected from the Show items when the value dropdown and then type in 1 in the input box below. Should be good to go after hitting "Apply filter."
If you need more information on this functionality. SQLBI has an article on this very subject here.
I have 2 date slicers and a measurement which is [Profit], I would like to return the difference in Profit given the date selections. Please see below for detail.
Date Slicer 1: 3/7/2021-3/13/2021
Date Slicer 2: 3/14/2021-3/20/2021
Profit given Date Slicer 1: 10
Profit given Date Slicer 2: 15
Value I am trying to get = 5 (15-10)
If the two slicers come from the same Date column, both periods do not intersect each other and you get a filter without dates.
Possibly there are better solutions but one of them would be to use a Harvester Filter (Creating an additional table containing a copy of the date column unrelated to the model, aka Disconnected Tables)
Before moving on to the next part you can verify that the filter contains the same dates but since it is a disconnected table, it does not filter the model, yet
For the [Profit given Date Slicer 1] you can use the original measure
For the [Profit given Date Slicer 2] you must change the filter to:
DATESBETWEEN(
'Dates'[Date],
MIN(HarvestingDates[Date]),
MAX(HarvestingDates[Date])
)
I am using a Matrix in PowerBI to show the Sales Manager and Sales Reps down the rows, and the different ship method and source of the order across the columns and a count of unique orders in the values.
Below shows the table structure I have, and I want to switch between "Show Values As": the original values I calculate with my measure (count of unique orders) and % of Row Total.
Currently, my only solution is to create a second table showing the different values, but I think that's a cheap solution. I've seen solutions with helper tables but since my values are a measure I cannot invoke them in other measures, and as the sources or ship methods are filtered I want the % of row total to reflect the filter as well so using a countx formula won't account for that (if I housed it in a formula).
I'm still somewhat new to the software so please bear that in mind.
Source 1 | Source 2 | Source 3
| Next Day; Ground; 2 Day | Next Day; Ground; 2 Day | Next Day; Ground; 2 Day
+Manager 1|
Rep 1 |
Rep 2 |
+Manager 2|
Rep 1 |
Rep 2 |
Looks like the best solution for you is to create bookmarks. You can create two tables, one showing the values and the other showing the %. Position the tables such that, one table is exactly on top of the other. Then create two bookmarks, one showing Table1 and the other showing Table2 (while hiding the other table using the "Selection Pane"). You can then use the bookmarks in a button action to toggle between Value and % views. The following link should give you further details on bookmarks:
https://learn.microsoft.com/en-us/power-bi/desktop-bookmarks
You can also do this by creating a measure which switches between values and %, but the formatting is going to be a pain point. I think bookmarks is your best bet.
You can create a parameter table (with no relationships to other tables in your model) to use as a slicer and a measure that switches between the two calculations based on a slicer selection.
Let's suppose you have measures [OrderCount] and [OrderCount%Total]. Then create a new table to use as a parameter ParamMeasure with a single column
Measure
-------
Count
%Total
You can now put ParamMeasure[Measure] as a slicer on your report and substitute the following measure instead of the existing ones.
OrderSwitch =
IF (
SELECTEDVALUE ( ParamMeasure[Measure] ) = "Count",
[OrderCount],
[Order%Total]
)
This way you don't need to create multiple visuals and bookmarks.
I am building a report in Power BI Desktop, created a slicer - YearMonthSort - which has data selection by Year-Month
Plz, see the screenshot below:
My goal is to limit data in this slicer as -
2015-07 to today's date
(whichever it will be when users will look at the data,
in the same format - "YYYY-MM")
In the "Filters" section I can select my starting year as 2015-07,
but having problem setting today's date.
I tried to create the new Measure, but not sure where to place it,
or, may be there is another way to perform this:
IsToday = FORMAT(TODAY(), "mm/yyyy")
I only just started to learn this,
Thank you for help in advance!
You can do the following:
I am assuming that you are using a calendar table that is joined to your fact table on a date field and that your year sort column is calculated with reference to the 'date' field in your calendar table.
Assuming, this is true you can create a calculated column that will flag whether or not the date field is before or after today. This can be achieved by using the following DAX:
IsToday =
SWITCH (
TRUE (),
'Calendar'[Date]
<= NOW (), 1,
0
)
Then, in your visual add a 'Visual Level Filter' using this new column and set it to 1.
I'm new to Power BI Desktop, coming from Excel.
In the query editor, I would like to create a new column in a table with the difference in time/date from one record to the next, by a separate grouping column (device). An example explains it better. Here's the starting point for the data, with one column for the device id, and another for the Date of the event.
Device Date
A 5/1/2016
B 5/1/2016
C 5/2/2016
A 5/4/2016
B 5/5/2016
A 5/10/2016
B 5/9/2016
C 5/12/2016
I would like to group by Device and Sort by Date, then calculate the differences, to make something like this:
Device Date Lag
A 5/1/2016 (null)
A 5/4/2016 3
A 5/10/2016 6
B 5/1/2016 (null)
B 5/5/2016 4
B 5/9/2016 4
C 5/2/2016 (null)
C 5/12/2016 10
What's the best way to do this in Power BI query editor?
Thanks for the help!
Here's a solution. But it does not involve Query editing.
we're gonna create a calculated column and do it the dax way.
1) In your Fields pane, right click on the table and Select "New
Column"
2) In the formula bar, type in the formula below. replace TableName with your table name
LagColumn = DATEDIFF(TableName[Date]
, CALCULATE(MAX(TableName[Date]),
FILTER(TableName,
TableName[Device] = EARLIER(TableName[Device]) &&
TableName[Date] < EARLIER(TableName[Date])
)
)
, DAY
)
3) Select Device, Date and the LagColumn in your report now. Choose "Table" option from the visualization panel.
Explanation of the formula -
1) The new lagColumn is the DATEDIFF in days of two entities.
2) First argument is the DATE field of the current row
3) Second argument is the maximum date value of all the dates that are less than the current row's date and that belongs to the same device as the current row. (EARLIER helps you retrieve the value of the current row in the previous context.)
read more here
1) EARLIER - https://msdn.microsoft.com/en-us/library/ee634551.aspx
2) Row Context and Filter Context - https://www.sqlbi.com/articles/row-context-and-filter-context-in-dax/
Screenshot of a similar use-case:
Here,
AccountAlternateKey corresponds to Date
ParentAccountAlternateKey
corresponds to Device, and
LagColumn is LagColumn
Note - For every group, lag of the first column is the first column itself. If you want it to be NULL, you can check if ISBLANK(CALCULATE....) is true and then make it null. that just adds a little bit complexity to the formula..
Proposing DAX solution since i don't think there is a query way to deal with this, AFAIK.
Let me know if you have any more questions..