Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
emarc1
Advocate II
Advocate II

Circular dependencies / calendar tables

I've always struggled to get multiple date relationships to work with calendar tables. In my data model, the Invoices table contains order dates, despatch dates and invoice dates (amongst many others but these are the important ones right now). I've made a relationship for Invoices[DateOrdered]<>Calendar[Date] and inactive relationships for DateDespatched and DateInvoiced.

 

Capture.PNG

 

I'm trying to calculate the length of time between when orders are placed and despatched using some of the work of Alberto Ferrari: http://sqlblog.com/blogs/alberto_ferrari/archive/2011/01/19/working-days-computation-in-powerpivot.a...

 

One column is made in Calendar that has a 1 for every working day and a 0 for every weekend day and holidays. Another column sums all of the dates before the current date:


01/01/2017, Sun, 0, 0 (Weekend)
02/01/2017, Mon, 0, 0 (Bank Holiday)

03/01/2017, Tue, 1, 1

04/01/2017, Wed, 1, 2

05/01/2017, Thu, 1, 3

06/01/2017, Fri, 1, 4

07/01/2017, Sat, 0, 4 (Weekend)

08/01/2017, Sun, 0, 4 (Weekend)

09/01/2017, Mon, 1, 5

...

 

You subtract the final WorkingDayNumber value for the order date from the value for the despatch date and you get the number of working days between them.

 

I then put two calculated columns into Invoices. Here's the one for DateOrdered:

CALCULATE(
VALUES( 'Calendar'[WorkingDayNumber] ),
'Calendar'[Date] = EARLIER( Invoices[DateOrdered] )
)

 

This creates a circular dependancy... So I tried using LOOKUPVALUE but I get the same problem! I thought LOOKUPVALUE was meant to get around relationship issues. If I deactivate the relationship between Calendar[Date] and Invoices[DateOrdered] (so now there are just three inactive relationships there) then either of these ways actually works perfectly... But it breaks everything else in my report that relies on that relationship. 

 

Any thoughts on how to get everything working here?

 

I can't share the pbix but I can take screen shots of things if it helps.

1 ACCEPTED SOLUTION
KHorseman
Community Champion
Community Champion

The problem is all the bi-directional crossfiltering. It's often better to leave the direction as Single on relationships and use the CROSSFILTER() formula only in the measures that absolutely require the Both directionality.





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!




View solution in original post

8 REPLIES 8
v-chuncz-msft
Community Support
Community Support

@emarc1,

 

You may learn to use USERELATIONSHIP Function.

Community Support Team _ Sam Zha
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

Thanks for your reply @v-chuncz-msft.

I think I've also tried that method before too.

 

With all of the date relationships inactive still, and the two calculated columns set out like this (the WorkingDayOrder column just uses Invoices[DateOrdered] <> Calendar[Date] instead):

 

Capture.PNG

 

That WorkingDayOrder works correctly but you can see here I get a circular dependancy with the WorkingDayDespatched column.

 

Here's the Calendar table for reference:

 

Capture2.PNG

 

Now if I'm thinking correctly... I can make the 'Calendar'[Date]<>'Invoices'[DateOrdered] relationship active and replace the WorkingDayOrdered column with:

WorkingDayOrdered = RELATED( 'Calendar'[WorkingDayNumber] )

And now there's no circular dependency but something's not quite right...

Capture3.PNG

 

Why is WorkingDayDespatch showing the same WorkingDayNumber as WorkingDayOrder when the dates that relate them are different? It's as if the USERELATIONSHIP is being ignored and the active relationship is taking priority.

@emarc1,

 

Here instead of calculated columns, use measures.

Community Support Team _ Sam Zha
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

@v-chuncz-msft

I'm still a little confused as to why Power BI was ignoring my USERELATIONSHIP syntax and favouring the active relationship instead. At least that's what I felt was happening... Strange behaviour.

 

Considering that the order and despatch date can be different for every line, it made more sense to do a calculated column so I could calculate the time to completion there too. The invoice table I have has close to 1 million rows for each year so aggregated figures should be quicker at the user end if I have my overall time to completion calculation done for each row already, shouldn't they?

 

Following your post, I looked up USERELATIONSHIP measures and read through this post from Our Lord Russo: http://www.sqlbi.com/articles/userelationship-in-calculated-columns/

 

I tried doing this measure, assuming a SUM would work okay... It doesn't seem to split the total value down per order number though:

 

 Capture.PNG

I'd be interested in knowing what I'm doing wrong in that measure.

 

---

 

Marco's blog post reminded me to try LOOKUPVALUE as a calculated column again and that seemed to be the ticket (WorkingDayOrder is still just using RELATED):

Capture2.PNG

 

So to conclude, I think @KHorseman was mostly on the money there. Using single direction filters on all of my date relationships allowed me to use LOOKUPVALUE properly.

 

Thanks, both of you, for nudging me in the right direction.

KHorseman
Community Champion
Community Champion

USERELATIONSHIP activates an inactive relationship, but it doesn't deactivate an active one. My impression is that the result is that it tries to use both relationships in that case. If I ever need multiple conflicting relationships, I just leave them all inactive and selectively turn them each back on with USERELATIONSHIP. Usually I will create a base measures like...

 

BaseSales = CALCULATE(
	SUM(SalesTable[Amount]),
	USERELATIONSHIP(
		DateTable[Date],
		SalesTable[Date]
	)
)

BasePurchase = CALCULATE(
	SUM(PurchaseTable[Amount]),
	USERELATIONSHIP(
		DateTable[Date],
		PurchaseTable[Date]
	)
)

Then I can do things like this:

 

Widget Sales = CALCULATE(
	[BaseSales],
	FILTER(
		SalesTable,
		SalesTable[Category] = "Widgets"
	)
)

Widget Purchases = CALCULATE(
	[BaseSales],
	FILTER(
		PurchaseTable,
		PurchaseTable[Category] = "Widgets"
	)
)

 

 





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!




Here's a screenshot of the relationships as they are set up for the second half of that last post: 

 

capture4.PNG

KHorseman
Community Champion
Community Champion

The problem is all the bi-directional crossfiltering. It's often better to leave the direction as Single on relationships and use the CROSSFILTER() formula only in the measures that absolutely require the Both directionality.





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!




@KHorseman

 

Thanks for your reply.

 

No change to anything immediately. It the WorkingDayOrder and WorkingDayDispatch still match. I'll experiment more tomorrow.

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.