I have the following tables & relationships in our pbix report:
For some obvious reasons, I need to have a relationship (non-active) between Dates[date] and Table2[T2Date]. However, doing so causes data fluctuation to measure 'Total Amount' in Table1.
Here are some screenshots:
Before Relationship (Dates[date] - Table2[T2Date]):
After Relationship (Dates[date] - Table2[T2Date]):
I need to understand why this difference is coming up and how the relationship is causing it since the measure uses a different relationship.
For reference, I am attaching the pbix report.
https://drive.google.com/open?id=1XknisXvElS6uQN224bEcZ_biX7m-4el4
Any help would be appreciated :)
The link that #MikeHoney gives has really useful information on the subtleties of relationships and does relate to this problem (do watch it!), but this issue is not ultimately related to bidirectional filtering in particular. In fact, I can reproduce it with this simplified relationship structure:
The key thing to note here is that when you attach Table2 to Dates, since Table2 contains T2Date values that don't match to any Date[date], this creates an extra row in Dates with a blank date which you can notice in your filter on 6. Year when that relationship exists (active or inactive). Filtering out that that blank in the 6. Year filter would work, except that in your measure, you use ALL(Dates) to strip all filtering done on that table.
There are multiple ways to resolve this discrepancy, the easiest being replacing ALL with ALLNOBLANKROW. If you used ALLSELECTED that would also work in conjunction with filtering out blanks on your report-level filter on 6. Year.
Cleaning up some items not relevant in this context and changing ALL to ALLNOBLANKROW, your total measure can be more simply written as:
ALLNOBLANKROW =
VAR EndServiceDate =
MAX ( Dates[Date] )
RETURN
CALCULATE (
SUM ( Table1[Net Amount] ),
FILTER (
ALLNOBLANKROW ( Dates ),
Dates[Date] <= EndServiceDate
),
Table1[Flag2] = 1,
Table1[Flag] = TRUE ()
)
Results with no 6. Year filter and with two measures, one using ALL and one using ALLNOBLANKROW:
Notice that every row in the ALL column has been reduced by -7,872.01. This is the sum of all the Net Amount values that don't match to any dates in the Dates table. If you remove the relationship from Dates[date] to Table2[T2Date] then the blank row no longer exists and both of these will match the ALLNOBLANKROW version.
Setting the Cross Filter Direction to Both on any relationship is a bit risky - you essentially hand over control of the runtime query designs to the Power BI robots. There's then a risk that they will come up with a "creative" query design that is unexpected.
There's some insight into how this happens in a recent talk by Alberto Ferrari:
https://www.sqlbi.com/tv/understanding-relationships-in-power-bi/
I'm sure you'll agree it's quite terrifying.
Looking at your info, I expect you can avoid those traps by changing the Cross Filter Direction to Single, for the relationship from MonthYear to Dates.
Related
I have a table from a survey that reports the score given to a specific employee, and various columns are there to hold each score for each question. Like this table below:
Now, what I want to do is make a row for each question, and in the original table, each question is a column. And I'd like for example, John, to have 1 entry for each question, and the average of that score stored next to each question like in this table here:
.
This shows clearly what I'm aiming for.
I believe I need some sort of pivot or unpivot table going on, but I'm not too sure on the Power BI DAX syntax for creating a new table.
I currently have a table that provides each Employee once, and columns showing their average score for each question, but that is a bit harder to dice up the way I want to. Code pasted below:
ReportTable =
SUMMARIZE(
ALL ( '360Sample'[Name], '360Sample'[Relationship to person being reviewed]),
'360Sample'[Name],
'360Sample'[Relationship to person being reviewed],
"Employee Satisfaction", DIVIDE(CALCULATE(AVERAGE('360Sample'[Treats others with respect/Truly values employees]))+AVERAGE('360Sample'[Encourages and supports staff in developing their skills])+AVERAGE('360Sample'[Provides effective mentoring]),3),
"Quality Product", DIVIDE(CALCULATE(AVERAGE('360Sample'[Consistently strives to provide products above industry quality standards]))+AVERAGE('360Sample'[Takes ownership of project outcome])+AVERAGE('360Sample'[Ensures quality control always happens on products]),3),
"Client Satisfaction", DIVIDE(CALCULATE(AVERAGE('360Sample'[Fosters open, honest, and consistent communication with clients]))+AVERAGE('360Sample'[Responds quickly to client questions and concerns.])+AVERAGE('360Sample'[Successfully communicates contractual needs and requirements with the Client, including schedules and scope and fee increases]),3),
)
Only difference here is that I have an extra attribute of "Relationship" which I'll also need to include but is less important for now. It makes a row of each employee for every unique Relationship, which is 2.
Hello You need to first use the "unpivot" in Power Query to convert your table into this shape: It is not so hard.
Like this:
Then use this DAX Code:
ReportTable =
ADDCOLUMNS (
SUMMARIZE ( 360Sample, 360Sample[Name], 360Sample[ScoreNum] ),
"ScoreAvg", CALCULATE ( AVERAGE ( 360Sample[Score] ) )
)
And It produces:
I am trying to understand the below DAX code:
CALCULATE(
SUM(Revenue[Net])
,FILTER('Center', NOT 'Center'[Acc] IN {"RSM", BLANK() })
,ALLSELECTED()
,VALUES('Customer'[Customer Number])
)
I have the below questions:
What's the use of ALLSELECTED?? By definition ALLSELECTED returns all rows in a table, ignoring any filters that might have been applied inside the query, but keeping filters that come from outside. https://dax.guide/allselected/
So, what's the point of writing FILTER() if its going to be forced to be ignored by the next line (ALLSELECTED)?!?
Also by definition:
CALCULATE is just a expresion followed by filters...
What's the use of VALUES() ? It doesn't appear to be a filter, so how is it even allowed to appear there? (Per definition VALUES(): returns a one-column table that contains the distinct values from the specified column.)
I do not understand what is this returning? is it the SUM() or the VALUES()?
(I come from a SQL background, so any sql-friendly answer is appreciated).
In Dax every filter is a table of values its look similar to INNER JOIN;
ALLSELECTED is useful when you need to keep a row context (this is also a filter in DAX). You can use ALLSELECTED inside FILTER function.
For better understand what engine does you can use a DaxStudio with ServerTiming;
As you see this product one simple statement:
SELECT
SUM ( 'Table'[Cost Centre] )
FROM 'Table'
WHERE
'Table'[Project] NIN ( 'AB' ) ;
You can find useful article by Alberto Ferrari and Marco Russo:
https://www.sqlbi.com/tv/auto-exist-on-clusters-or-numbers-unplugged-22/
If it is only converting DAX queries if your connecting your sql analysis services to in DAX studio. because it is not working for PBI file data
I have a table Deals which has columns [DealId], [Open Date Id], [Closed Date Id] where the last 2 columns are like a foreign key to the Date table which has [Date], [DateId] column.
Power BI won't let me have 2 active relationship, so one is inactive.
Now I want to create some visuals indicating the deals that were open and closed in a custom range of time (using slicer).
How I tried to solve
The closest solution to this was creating a calculated column with the LOOKUPVALUE and adding the close and open dates directly to Deals table. And created 2 different pages with 2 different slicers, but this is far not the solution I wanted.
How can I solve this problem?
I don't know if what I'm going to say suits your needs based on the size of the tables or the rigidity of the data model due to other measures. I think that in the end what matters is to understand what are the limitations of what you want to show. However, something almost similar I answered here: https://stackoverflow.com/a/66792957/15460989
From what I could understand you have two tables similar to:
Deals = {[DealID] [OpenDate] [CloseDate] [Quantity] [Price] ...}
Dates = {[Date] [MonthName] [MonthNumber] [Year] ...}
And you want to filter Deals based on two relationships
USERELATIONSHIP (Dates [Date], Deals [OpenDate])
USERELATIONSHIP (Dates [Date], Deals [CloseDate])
I am not going to discuss the option of duplicating Dates Table because it was previously covered using two slicers.
But what if the characteristics of my model allow me to use a table with two relationship (One active and the other inactive) while my visualization uses the content of an unrelated table?
Let's define my new unrelated table as:
HarvestingDates = {[Date] [MonthName] [MonthNumber] [Year] ...}
and what I'm trying to achieve is something like this:
From a model like this one:
Deals[DealID]: Unique values.
Deals[OpenDate]: Repeated and missing dates
Deals[CloseDate]: A random number between 0 and 5 is added to Deals [OpenDate]
Instead of choosing an opening date and a closing date, I choose a date range not related to the model and the context related to the deals comes from the measures. Example:
Opened Deals: All the deals opened in a certain date range and summarized by the visualization.
HOpenedDeals: =
CALCULATE(
COUNTROWS(Deals),
TREATAS(
VALUES(HarvestingDate[Date]),Dates[Date]
)
)
Closed Deals: All the deals closed in a certain date range and summarized by the visualization.
HClosedDeals:=
CALCULATE(
COUNTROWS(Deals),
USERELATIONSHIP(Dates[Date],Deals[CloseDate]),
TREATAS(VALUES(HarvestingDate[Date]),Dates[Date])
)
Open and closed deals: All open and closed deals in the same date range summarized by the visualization
HOpened&Closed :=
VAR TotalRow= SUMMARIZE(HarvestingDate,HarvestingDate[Year],HarvestingDate[MonthName])
VAR CurrentDates=VALUES(HarvestingDate[Date])
VAR Result=
ADDCOLUMNS(TotalRow, "Count",
VAR CurrentMonthName= {CALCULATE(VALUES(HarvestingDate[MonthName]))}
VAR CurrentYear= {CALCULATE(VALUES(HarvestingDate[Year]))}
RETURN
COUNTROWS(INTERSECT(
CALCULATETABLE(Deals,
USERELATIONSHIP(Dates[Date],Deals[CloseDate]),
TREATAS(CurrentMonthName, Dates[MonthName]),
TREATAS(CurrentYear, Dates[Year]),
TREATAS(CurrentDates, Dates[Date])
),
CALCULATETABLE(Deals,
TREATAS(CurrentMonthName, Dates[MonthName]),
TREATAS(CurrentYear, Dates[Year]),
TREATAS(CurrentDates, Dates[Date])
)
)))
RETURN SUMX(Result,[Count])
Opened & Not Closed Deals: All open and non-closed deals in the same date range summarized by visualization
HO&NOTC :=
VAR TotalRow= SUMMARIZE(HarvestingDate,HarvestingDate[Year],HarvestingDate[MonthName])
VAR CurrentDates=VALUES(HarvestingDate[Date])
VAR Result=
ADDCOLUMNS(TotalRow, "Count",
VAR CurrentMonthName= {CALCULATE(VALUES(HarvestingDate[MonthName]))}
VAR CurrentYear= {CALCULATE(VALUES(HarvestingDate[Year]))}
RETURN
COUNTROWS(EXCEPT(
CALCULATETABLE(Deals,
TREATAS(CurrentMonthName, Dates[MonthName]),
TREATAS(CurrentYear, Dates[Year]),
TREATAS(CurrentDates, Dates[Date])
),
CALCULATETABLE(Deals,
USERELATIONSHIP(Dates[Date],Deals[CloseDate]),
TREATAS(CurrentMonthName, Dates[MonthName]),
TREATAS(CurrentYear, Dates[Year]),
TREATAS(CurrentDates, Dates[Date])
)
)))
RETURN SUMX(Result,[Count])
TEST
Date range: {5/27/2021…5/31/2021}
I am sure this can be improved but as I said at the beginning it is just an idea. Cheers!
In this case the easiest way is to implement a role playing dimension functionality by duplicating your date table. Power BI engine does not support role playing dimensions, so the workaround for small tables is just duplicating them, as described in this article.
In your case, you could create a table "Date_for_closed" using
Date_for_closed = ALL('Date')
This creates a copy of your original Date table. Then you can create relationships and only have active ones. This way it is even easier to maintain than a bunch of inactive relationships.
With this implemented you can build this:
from this source:
I have a table that looks like this. Table Screenshot
"FY 20-21 (Budgeted)", "FY21 Approved Budget" and "Revised Budget" are columns coming from three different data sources that I appended into one table. There isn't always data in all three of these columns, so I created a new column to consolidate the data with the following formula:
FY 20-21 Budget =
if(
and(
isblank('Comprehensive Budget'[FY 20-21 (Budgeted)]),
isblank('Comprehensive Budget'[FY21 Approved Budget])
),
'Comprehensive Budget'[Revised Budget],
if(
and(
isblank('Comprehensive Budget'[FY21 Approved Budget]),
isblank('Comprehensive Budget'[Revised Budget])
),
'Comprehensive Budget'[FY 20-21 (Budgeted)],
'Comprehensive Budget'[Revised Budget]
)
)
If both Budgeted and Approved are blank, use Revised.
If not, if both Revised and Approved are blank, use Budgeted.
If not, use Revised.
But if you look on the screenshot, if NONE of the columns are blank, it gives me Revised plus Budgeted. Where is the problem in my formula?
I have added your data here and found your Measure is perfectly returning your expected data as shown in the below image-
I Guess, there are some Aggregation issue in your case. You can right click on all column in the table visual properties and select Don't Summarize from the options. This should solve your issue I hope.
Basically, I’d like to get one entity totals, but calculated for another (but still related/associated!) entity. Relation type between these entities is many-to-many.
Just to be less abstract, let’s take Trips and Shipments as mentioned entities and Shipments’ weight as a total to be calculated.
Calculating weight totals just per each trip is pretty easy task. Here is a table of Shipments weights:
We place them into some amounts of trucks/trips and get following weight totals per trip:
But when I try to show SUM of Trip weight totals (figures from 2nd table) per each related Shipment (Column from 1st table), it becomes much harder than I expect.
It should look like:
And I can’t get such table within Power BI.
Data model for your reference:
Seems like SUMMARIZE function is almost fit, but it doesn’t allow me to use a column from another table than initialized in the function:
Additional restrictions:
Selections made by user (clicks on cells etc.) should not affect calculation anyhow.
The figures should be able to be used in further calculations, using them as a basis.
Can anyone advise a solution? Or at least proper DAX references to consider? I thought I could find a quick answer in DAX reference guide on my own. However I failed to find a quick answer.
Version 1
Try the following DAX function as a calculated column inside of your shipments table:
TripWeight =
VAR tripID =
RELATED ( Trips[TripID] )
RETURN
CALCULATE (
SUM ( Shipments[ShipmentTaxWeightKG] );
FILTER ( Shipments; RELATED ( InkTable[TripID] ) = tripID )
)
The first expression var tripID is storing the TripID of the current row and the CALCULATE function gets the SUM of all of the weight for all the shipments that belong to the current trip.
Version 2
You can also create a calculated table using the following DAX and create a relationship between the newly created table and your Trips table and simply display the weight in this table:
TripWeight =
GROUPBY (
Shipments;
Trips[TripID];
"Total Weight KG"; SUMX ( CURRENTGROUP (); Shipments[ShipmentTaxWeightKG] )
)
Version 3
Version 1 and 2 are only working if the relationship between lnkTrip and Shipment is a One-to-One relationship. If it is a many-to-one relationship, the following calculated column can be created inside of the Trips table:
ShipmentTaxWeightKG by Trip = SUMX(RELATEDTABLE(Shipments); Shipments[ShipmentTaxWeightKG])
hope this helps.