3 table complex loop join

I know, I know I searched I promise, but I am having problem with the terminology of trying to search based on my question.

Three tables A, B, and C. I need to create objects based on table C dependent on 4 values from table A and 1 from table B. Problem is, table A and B are joined and need to be, thus I have a loop. I am familiar with context and alias but not sure they will work for this situation. A context would define the correct path, but I really need both paths A-> C and B-> C defined in my join to return the correct values.

Right now, I have join A->C and place and then force join B->C in the where clause of the object. It looks like this will work but I do not know that this is the best solution.

Thoughts? Suggestions?


jswoboda :us: (BOB member since 2002-06-20)

Jeff:

Not all loops are a “bad thing”. If you need a loop in your universe, simply create a context that includes all of the joins from A, B, and of course C and let it go at that. BusinessObjects will then generate the sql code that includes a loop.

Put another way. If you have tables A, B, and C, and you do not do anything to resolve the loop, then BusinessObjects will complain. But if you say that the loop is okay by including every join in a context, then it will happily generate the correct SQL.

I have used this technique and it works just fine. For example, there was a universe where I needed three tables: the service provider, the service, and the customer. The customer may get one service from one service provider and a different service from a different service provider all on the same transaction. Think of a hospital stay… you have surgery, but the surgeon doesn’t do the anesthesia. You need the combination of all three entities (provider, service, customer) to get a valid result.

The issue may be that if you do this, then you will always get the sql with the loop in it…

Alternatively you can create a view with A, B, and C in it, then simply use the view in your universe. That isolates the loop at the database level, and BusinessObjects is none the wiser. :wink:

Dave


Dave Rathbun :us: (BOB member since 2002-06-06)

Just out of curiosity, would it also work to make one of the joins a shortcut join? I don’t know . . . I’m just tossing out an idea. :confused:


MichaelWelter :vatican_city: (BOB member since 2002-08-08)

Thanks for the feedback guys.

My problem with context are - once you use a context everthing must then be included in a context. Right now, this is a somewhat significant Universe and there are no context defined. We would need to go back and create all the context. We have considered the view; however, I am just trying to determine all my options and make the best decision.

I think the problem with a shortcut join (although technically the loop would be resolved) is - only one path is used and in this case if objects from all three tables are used it would always use the primary joins to associate the tables thus leaving out the necessary shortcut.

Do you guys think defining all the context or creating the view would provide a better solution that the one I suggested earlier (forcing the last join into the where clause of the object). Do you see anything inheritantly wrong with this?

Thanks


jswoboda :us: (BOB member since 2002-06-20)

I have had similar experiences both with Oracle and SQL Server. In both cases, I create an alias table.

With Oracle, I use an nvl function which will use the table where the criteria exists and ignore the other.

With SQL Server, I use ISNULL(Table1.Field,Table1_alias.Field)

I have also used aliases in a series. However, in my case there was another Key table involved as well.

Good Luck.


tkdrocks :us: (BOB member since 2003-06-10)

As Dave suggested initially, have you explored the possibilities of using a view at the database end…?


Anjan Roy (BOB member since 2002-07-10)

Yes have considered the view, just trying to explore all possiblities and determine best solution for our needs.


jswoboda :us: (BOB member since 2002-06-20)

So just create one context that includes the entire universe. 8) There’s nothing wrong with that. The point is, if you have an unresolved loop in your universe, BusObj won’t generate the sql. But as long as you have made an attempt to resolve it - and including a loop in a context is not the “typical” result but there is nothing wrong with it - then it will happily generate the sql that includes joins from A, B, and C all at the same time.

Dave


Dave Rathbun :us: (BOB member since 2002-06-06)

thanks Dave


jswoboda :us: (BOB member since 2002-06-20)

The problem is if you have more than one object, you will have to add the clause to each object. Not very elegant, especially from a maintenance standpoint.


JF Cayron :us: (BOB member since 2002-08-15)

I just ran into the very same problem: I believe the best solution would be to de-normalize the tables.


Andreas :de: (BOB member since 2002-06-20)

I vote for the view thing. I don’t think a context is the answer. Just because joins exist in the context, doesn’t mean they will be used. You would still have the problem of forcing the B->C join. You could do it the way your are or by using the Tables button on the objects and then having a true join in the universe.


Steve Krandel :us: (BOB member since 2002-06-25)

I also ran in similar problem. I think creating a view would be the best solution to this problem. Or if that is not possible, a very crude soln in case there is only 1 such object in the universe that needs to go over all three tables would be to
add the join b/w those two remaining tables in the WHERE clause of that object in the universe

Reema


reemagupta (BOB member since 2002-09-18)

Thanks for everyone’s feedback. After careful consideration and testing it does appear that a view will be used to resolve this issue.


jswoboda :us: (BOB member since 2002-06-20)

I am facing a similar problem. Creating only one context for the whole universe works only if you have only one loop or if you want to force the loops all at the same time into your SQL code.

My scenario differs:
I have multiple loops, which are necessary (denormalized tables/ PeopleSoft). If I have two loops L1 and L2 and I want for one table to force loop L1, but not loop L2 I have to create separate multiple contexts.


Andreas :de: (BOB member since 2002-06-20)

I need to force my universe to loop based on a single Time dimension table joined to many type 2 / versioned dimension tables. Each of these are then joined to each other in a hierarchal fasion. For example the tables could be UPC / Product / Category. Each of these are versioned in it’s table by effective and end dates. The problem is that if I want a report showing which Categories were effective in a given week, BO will also join the Time table to the other 2 dimension tables. In my case, there are 7 very large versioned tables, and I can’t have all 7 included in every query, even if I just want time and a single dimension. I can try creating every combination of contexts possible, but BO will still prompt for which context to use, which we can’t allow. Is it possible to either limit which joins of this type of context are used to the shortest join path, or have BO automatically use a context based on fewest joins. I don’t think this is possible… but thought I’d ask.


paulmaric (BOB member since 2004-02-09)

I’ve got an issue that seems to belong in this thread. The objective is to be able to report how much time an employee works on any PROJOWNER’s projects (there are approx a dozen PROJOWNERs) , and the total time worked on all projects. I can get this to work fine using a subquery, but I also need it to work with webI 2.6 (I know subqueries work in v6, but we’re not quite there yet). I’m trying to get BO to mimic the following sample SQL, which produces the desired result:

SELECT   c.EMPID,  c.FULLNAME,
  sum(( CASE  WHEN  ( b.PROJOWNER ) = 'Bert, Rat' THEN ( a.ACTUALHRS ) ELSE 0.00 END )),
  sum(( a.ACTUALHRS ))
FROM v_pt_Resource_Time_MON a  
 left join v_pt_project_code b ON   b.projectcodeID= a.PROJECTCODEID
 left JOIN v_pt_people_info c ON a.EMPID= c.AEMPID
WHERE  (   a.yearmonthend  =  200404  )
GROUP BY
  1, 
  2
HAVING
  (   sum(( CASE  WHEN  ( b.PROJOWNER ) = 'Bert, Rat' THEN ( a.ACTUALHRS ) ELSE 0.00 END ))  >  0  )
ORDER BY
  4   DESC

I’ve set up a context with the three tables. I have one object that sums total actual hours, and another with an owner’s name and sums for owner-specific hours:

 @Aggregate_Aware(sum(CASE WHEN v_pt_project_code.projowner= 'Bert, Rat' Then v_pt_Resource_Time_MON.ACTUALHRS Else 0.00 END),sum(CASE WHEN v_pt_project_code.projowner= 'Bert, Rat' Then v_pt_res_proj_hours.ACTUALHRS Else 0.00 END)) 

If I don’t set up a subquery to return EMPIDs where the sum of PROJOWNER hours is greater than 0, I get all employees, whether or not they had hours for the specific PROJOWNER. Both objects return the correct sum of hours, but we don’t want to see the employees with zero for that specific owner. I’m wondering if the desired SQL can be forced somehow, or is this yet another case best resolved by views?


charlie :us: (BOB member since 2002-08-20)

Not sure if I understand you correctly:

 HAVING 
SUM
( 
CASE  WHEN  b.PROJOWNER  = 'Bert, Rat' 
   THEN a.ACTUALHRS  
   ELSE 0.00 
END
)  >  0 

This is not a subquery and you should be able to create this condition in a WebI report as well.

Maybe, you can post the Business Objects generated SQL that does not return the desired results?


Andreas :de: (BOB member since 2002-06-20)

Sorry, let me clarify. The subquery was created by dragging EMPID to the conditions panel, choosing In List as the operator, and Create a subquery as the operand. Then on the subquery panel, EMPID as the result, and a condition where sum of actual hours (specific owner) > 0.


charlie :us: (BOB member since 2002-08-20)

Paulmaric,

Why can’t you use aliased Time dimension tables? Try it out; I think it should give you what you want.

Two threads on this topic are Linking Summary Tables for aggregate aware and Time condition in two contexts (shared calendar dimension).


JP Brooks :us: (BOB member since 2002-10-22)