Why left outer join is happening between two queries
Hi, I have 2 facts in my request. So 2 queries are getting generated D1 and D2. But OBIEE is doing a D1 left outer join on D2. I am not understanding from where this left outer join is coming. I want an inner join. Can anybody help.
thx,
parag
Hi Parag,
Can you please check it in your BMM layer column mapping and double click you join here you can find type option. Please change to type inner.
Go--> BMMLayer--> double click column Joins--> Type--> you can change what type you want.
Award Points it is useful.
Thanks,
Satya
Similar Messages
-
Left Outer Join with more than two tables in both CR 8.5 and XIR2
I am trying to create a report and I have tried two versions of Crystal but I ultimately need the report in CR8.5 for compatibility with the client's system. I think I am starting to figure out what might be wrong and it might be my understanding of SQL, but I can't see why someone hasn't needed this in the past. Ultimately I want to see all projects and any journal entry that might be posted for that project.
Database is MySQL 5.0.38 and using MySQL ODBC driver 3.51.19.
Project header table information will be populated. Each line item on a journal entry can be tagged with the project ID. But for me to pull the journal entry date I need also to link to a third table for the journal entry header info.
I want to see all projects, whether a journal entry has been posted or not.
So the links are like this
ProjectHeader --->Left Outer Join ---> JELines ---> Inner Join ---> JEHeader
I think in this scenerio Crystal is treating the LOJ as an IJ.
I created two brand new reports today, one in CR8.5 and one in CR XIR2. Once I edited the automatic CR8.5 SQL statement (which I have been doing for years, usually without problem), they both ran properly. I linked customers to their invoices. Customers without invoices showed properly. But then I linked the invoices to the payments of the invoices and immediately lost customers without orders in both reports.
So apparently only two tables are allowed in Outer Joins. Does this make sense? I checked out the w3schools tutorial on SQL and it doesn't mention this limitation and I can't find anywhere else that it specifically indicates this but all samples of code I have seen only show two tables. I just thought for presentation as a sample that was easiest to understand and we could expand as necessary.
If this is correct, how does one go about accounting for this kind of thing? One solution that goes through my mind is creating a view at the database level for the link between journal entry lines and journal entry headers. Would this be a good solution under normal circumstances?
A second option that I had to implement because of timelines, is to use a subreport linked to the main report through the project ID to pull the information for the journal entries and just pass the totals I need to the main report through a shared variable.
These aren't normal circumstances because I don't have access to the database so I can't create the view. I have come across this concept several times and I have been able to use subreports to solve it but I am trying to find a better solution for the future as sometimes subreports can be slow. So are there any alternatives I have not considered here?
TIA rasincSo after some more work and another post. I was able to get this to work.
Items disappear when linking to another table
My issues were two fold. I was selecting on the tables on the right-side of the original Inner Join. However, I was checking for Nulls. This apparently is correct but you must check for the Nulls first eg. (IsNull (JEHeader.Field1) OR JEHeader.Field1 <= 100). I had my original statement reversed checking for <= 100 before checking for Nulls.
I also did not set all links to be Left Outer Join. I had the Inner Join. I actually have about 6 tables in this report so all the links need to be set Outer Join. So this now seems to be corrected.
Thanks -
Why Left Outer Join Doesn't Work?
Hello
I have a query that I want to return all group id's in the grp_id table and count and give me a count of all members that are "active" in the member table. There are some members that are not active in the member table that belong to groups in the grp_id table. I still want a record returned for those grpid's, though since there are no active members for those groups, I would want a zero as the mbr_count. An active mbr is one whose eff_dt is less than today's date and whose exp_dt is greater than todays date.
I have listed the query below, which returns active mbr records, but unfortuntely, does not return the one grpid (as in my sample data) that does not have an active member (grpid: 'D'). I have also provided the DDL for the two tables along with some sample data that gives me the (Incorrect) results I have posted. I have also posted what results I need (the 'Correct' results).
Thanks for any assistance.. (I am using PL/SQL)
QUERY I AM USING:
=============
SELECT
g00.grpid,
count(m00.grpid) mbr_count
FROM
grp_id g00
LEFT OUTER JOIN
mbr m00 on
g00.grpid = m00.grpid
WHERE
m00.eff_dt < sysdate
AND
m00.exp_dt > sysdate
GROUP BY
g00.grpid
it gives me results as:
INCORRECT RESULTS:
===============
GRPID MBR_COUNT
A 2
B 2
C 1
What I want to see is:
CORRECT RESULTS
===============
GRPID MBR_COUNT
A 2
B 2
C 1
D 0
Here is the DDL's and Sample Data:
create table grp_id (grpid varchar(1))
insert into grp_id values ('A')
insert into grp_id values ('B')
insert into grp_id values ('C')
insert into grp_id values ('D')
commit
create table mbr (mbr_name varchar(10), grpid varchar(1), eff_dt date, exp_dt date)
insert into mbr values ('MARK', 'A', to_date('01-01-2011', 'MM-DD-YYYY'), to_date('07-01-2011', 'MM-DD-YYYY'))
insert into mbr values ('MARK', 'A', to_date('07-01-2011', 'MM-DD-YYYY'), to_date('01-01-2012', 'MM-DD-YYYY'))
insert into mbr values ('MARTY', 'A', to_date('01-01-2011', 'MM-DD-YYYY'), to_date('07-01-2011', 'MM-DD-YYYY'))
insert into mbr values ('MARTY', 'A', to_date('07-01-2011', 'MM-DD-YYYY'), to_date('01-01-2012', 'MM-DD-YYYY'))
insert into mbr values ('FRANK', 'B', to_date('01-01-2011', 'MM-DD-YYYY'), to_date('07-01-2011', 'MM-DD-YYYY'))
insert into mbr values ('FRANK', 'B', to_date('07-01-2011', 'MM-DD-YYYY'), to_date('01-01-2012', 'MM-DD-YYYY'))
insert into mbr values ('MARY', 'B', to_date('01-01-2011', 'MM-DD-YYYY'), to_date('07-01-2011', 'MM-DD-YYYY'))
insert into mbr values ('MARY', 'B', to_date('07-01-2011', 'MM-DD-YYYY'), to_date('01-01-2012', 'MM-DD-YYYY'))
insert into mbr values ('JEAN', 'C', to_date('01-01-2011', 'MM-DD-YYYY'), to_date('07-01-2011', 'MM-DD-YYYY'))
insert into mbr values ('JEAN', 'C', to_date('07-01-2011', 'MM-DD-YYYY'), to_date('01-01-2012', 'MM-DD-YYYY'))
insert into mbr values ('NOAM', 'D', to_date('01-01-2011', 'MM-DD-YYYY'), to_date('07-01-2011', 'MM-DD-YYYY'))Thanks for the script, shame about the missing semi-colons :)
Your restrictions on date are implemented as "filter predicates" rather than "join predicates".
i.e. the difference between a WHERE instead of extra ANDs in the JOIN clause.
SQL> SELECT
2 g00.grpid,
3 count(m00.grpid) mbr_count
4 FROM
5 grp_id g00
6 LEFT OUTER JOIN
7 mbr m00 on
8 g00.grpid = m00.grpid
9 WHERE
10 m00.eff_dt < sysdate
11 AND
12 m00.exp_dt > sysdate
13 GROUP BY
14 g00.grpid
15 /
G MBR_COUNT
A 4
B 4
C 2
SQL> SELECT
2 g00.grpid,
3 count(m00.grpid) mbr_count
4 FROM
5 grp_id g00
6 LEFT OUTER JOIN
7 mbr m00 on
8 g00.grpid = m00.grpid
9 AND
10 m00.eff_dt < sysdate
11 AND
12 m00.exp_dt > sysdate
13 GROUP BY
14 g00.grpid;
G MBR_COUNT
D 0
A 4
B 4
C 2
SQL> -
Display all dates between date range (Time Dimension left outer join Fact)
All,
I have done some searching around this issue but within all the posts regarding date variables, date prompts and date filtering I haven't seen one exactly answering my issue (maybe they are and I just dont have my head around it correctly yet).
My report requirement is to allow a user to select a start day and an end day. The report should show all activity between those two days - AND display 0/null on days where there is no activity. That second part is where I am getting hung up.
The tables in question are:
TimeDim
EventFact
CustomerDim
My BMM is setup as follows:
TimeDim left outer join EventFact
CustomerDim inner join EventFact
If I run a report selecting DAY from TimeDim and a measure1 from EventFact with day range 1/1/2010 - 12/31/2010 .. I get a record for every day and it looks perfect because of the left outer join between TimeDim and CustomerDim.
But .. if I add in a field from CustomerDim, select TimeDim.DAY, CustomerDim.CUSTNAME, EventFact.MEASURE1, OBIEE only returns records for the days that have EventFact records.
This is due to the fact that the TimeDim is still outer joined into EventFact but adding in CustomerDim makes OBIEE setup an inner join between those tables which then causes only data to be returned where EventFact data exists.
There is a way around this in this simple case and that is to define the relationship between CustomerDim and EventFact as an outer join as well. This will give the desired effect (but an outer join between these two tables is not the true relationship) and as I add additional dimensions and add additional logical sources to a single dimension in the BMM it gets complicated and messy.
Ive also messed with setting the driving table in the relationship, etc.. but it has not given the desired effect.
Has anyone ever encountered the need to force display all dates within a specfied range with a fact table that may not have an entry for every date?
Thanks in advance.
K
Edited by: user_K on Apr 27, 2010 11:32 AMIt worked!!!* Even my time drill downs and date based filtering still work!
That is awesome. Never would have thought of that intuitively.
Now, just need a little help understanding how it works. When I run my report and check the logs I can see that two queries are issued:
Query 1: Joins the fact table to all the associated dimensions. I even changed all the relationships to inner joins (which is what they truly are). And calculates the original measure. If I copy and paste this query into sql developer it runs fine but only returns those rows that joined to the time dimension - which is what was happening before. It is correct but I wanted a record for every time dimension record.
Query 2: Looks like the following:
select sum(0)
from timedim
where date between <dateprompt1> and <dateprompt2>
group by month *<--* this is the time dimension level specified in Query 1, so it knows to aggregate to the month level as was done in query 1
Final Question: So what is OBIEE doing ultimately, does it issue these two requests and then perform a full outer join or something to bring them together? I couldn't see anywhere in the log a complete query that I could just run to see a similar result that I was getting in Answers.
Thanks for all the help .. Id give more points if I could.
K -
Difference between merge-Not matched and left outer join
Why should Merge-Not Matched be used instead of left outer join? I believe both will enable comparison of 2 tables. So what is the difference. Please advice.
mayooran99MERGE is way to encapsulate all conditions within single statement
The equivalent implementation using join would require three different statements
1 UPDATE using INNER JOIN
1 INSERT using LEFT JOIN
and 1 DELETE using LEFT JOIN in reverse order
Both approaches work fine
so all that you need to do is left join operation to find difference you can use either
But MERGE has one additional advantage in case you need to get output from MERGE and use it for further manipulation like further insert to child table
I've explained it here
http://visakhm.blogspot.in/2014/09/t-sql-tips-multifaceted-merge-statement.html
Please Mark This As Answer if it solved your issue
Please Vote This As Helpful if it helps to solve your issue
Visakh
My Wiki User Page
My MSDN Page
My Personal Blog
My Facebook Page -
Performance difference between left outer join / inner join
Hi,
I've got a complex query which among other things accesses quite a large table. If I use inner join to join this table, the response is quite fast and execution plan shows it uses nested loops to gather the data.
If I change inner join to left outer join, I get a big performance drop. Cost of query goes from 1441 to 28544.
I don't uderstand why there's such a difference. For inner join, database has to remove all the rows that don't have match in inner-joined table. For left join it can keep all records and just return NULL values for records that don't have a match. In my mind left join should be faster, as it seems simpler. And the access plan could be the same, couldn't it?
Execution plan for inner join:
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 288 | 1441 (1)| 00:00:18 |
| 1 | HASH GROUP BY | | 1 | 288 | 1441 (1)| 00:00:18 |
| 2 | NESTED LOOPS OUTER | | 1 | 288 | 1440 (1)| 00:00:18 |
| 3 | NESTED LOOPS | | 1 | 261 | 1438 (1)| 00:00:18 |
| 4 | NESTED LOOPS | | 318 | 74412 | 508 (1)| 00:00:07 |
| 5 | NESTED LOOPS | | 318 | 51834 | 189 (0)| 00:00:03 |
| 6 | TABLE ACCESS BY INDEX ROWID| RESURCE | 1 | 106 | 1 (0)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN | RESURCE_PRINCIPAL_NAME_INDEX | 1 | | 0 (0)| 00:00:01 |
| 8 | TABLE ACCESS BY INDEX ROWID| TASK_USES_RESURCE | 318 | 18126 | 188 (0)| 00:00:03 |
|* 9 | INDEX RANGE SCAN | TASK_USES_RESUR_IDX$$_0CDC0002 | 318 | | 3 (0)| 00:00:01 |
| 10 | TABLE ACCESS BY INDEX ROWID | TASK | 1 | 71 | 1 (0)| 00:00:01 |
|* 11 | INDEX UNIQUE SCAN | TASK_PK | 1 | | 0 (0)| 00:00:01 |
| 12 | TABLE ACCESS BY INDEX ROWID | TASK_WORK_HISTORY | 1 | 27 | 3 (0)| 00:00:01 |
|* 13 | INDEX RANGE SCAN | TASK_WORK_HISTORY_INDEX1 | 1 | | 2 (0)| 00:00:01 |
| 14 | TABLE ACCESS BY INDEX ROWID | TASK_USES_RESURCE | 1 | 27 | 2 (0)| 00:00:01 |
|* 15 | INDEX UNIQUE SCAN | TASK_USES_RESURCE_UK1 | 1 | | 1 (0)| 00:00:01 |
For left outer join:
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 318 | 1596K| | 28544 (2)| 00:05:43 |
|* 1 | HASH JOIN OUTER | | 318 | 1596K| 1584K| 28544 (2)| 00:05:43 |
| 2 | VIEW | | 318 | 1580K| | 508 (1)| 00:00:07 |
| 3 | NESTED LOOPS | | 318 | 74412 | | 508 (1)| 00:00:07 |
| 4 | NESTED LOOPS | | 318 | 51834 | | 189 (0)| 00:00:03 |
| 5 | TABLE ACCESS BY INDEX ROWID| RESURCE | 1 | 106 | | 1 (0)| 00:00:01 |
|* 6 | INDEX UNIQUE SCAN | RESURCE_PRINCIPAL_NAME_INDEX | 1 | | | 0 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID| TASK_USES_RESURCE | 318 | 18126 | | 188 (0)| 00:00:03 |
|* 8 | INDEX RANGE SCAN | TASK_USES_RESUR_IDX$$_0CDC0002 | 318 | | | 3 (0)| 00:00:01 |
| 9 | TABLE ACCESS BY INDEX ROWID | TASK | 1 | 71 | | 1 (0)| 00:00:01 |
|* 10 | INDEX UNIQUE SCAN | TASK_PK | 1 | | | 0 (0)| 00:00:01 |
| 11 | VIEW | | 1480K| 73M| | 23431 (2)| 00:04:42 |
|* 12 | HASH JOIN RIGHT OUTER | | 1480K| 76M| 38M| 23431 (2)| 00:04:42 |
| 13 | TABLE ACCESS FULL | TASK_USES_RESURCE | 1486K| 21M| | 2938 (2)| 00:00:36 |
| 14 | VIEW | | 1445K| 53M| | 15031 (2)| 00:03:01 |
| 15 | HASH GROUP BY | | 1445K| 37M| 110M| 15031 (2)| 00:03:01 |
| 16 | TABLE ACCESS FULL | TASK_WORK_HISTORY | 1445K| 37M| | 3897 (2)| 00:00:47 |
--------------------------------------------------------------------------------------------------------------------------...continued
Complete execution plan for left join:
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 318 | 1594K| | 28544 (2)| 00:05:43 |
|* 1 | HASH JOIN OUTER | | 318 | 1594K| 1584K| 28544 (2)| 00:05:43 |
| 2 | VIEW | | 318 | 1578K| | 508 (1)| 00:00:07 |
| 3 | NESTED LOOPS | | 318 | 74412 | | 508 (1)| 00:00:07 |
| 4 | NESTED LOOPS | | 318 | 51834 | | 189 (0)| 00:00:03 |
| 5 | TABLE ACCESS BY INDEX ROWID| RESURCE | 1 | 106 | | 1 (0)| 00:00:01 |
|* 6 | INDEX UNIQUE SCAN | RESURCE_PRINCIPAL_NAME_INDEX | 1 | | | 0 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID| TASK_USES_RESURCE | 318 | 18126 | | 188 (0)| 00:00:03 |
|* 8 | INDEX RANGE SCAN | TASK_USES_RESUR_IDX$$_0CDC0002 | 318 | | | 3 (0)| 00:00:01 |
| 9 | TABLE ACCESS BY INDEX ROWID | TASK | 1 | 71 | | 1 (0)| 00:00:01 |
|* 10 | INDEX UNIQUE SCAN | TASK_PK | 1 | | | 0 (0)| 00:00:01 |
| 11 | VIEW | | 1480K| 73M| | 23431 (2)| 00:04:42 |
|* 12 | HASH JOIN RIGHT OUTER | | 1480K| 76M| 38M| 23431 (2)| 00:04:42 |
| 13 | TABLE ACCESS FULL | TASK_USES_RESURCE | 1486K| 21M| | 2938 (2)| 00:00:36 |
| 14 | VIEW | | 1445K| 53M| | 15031 (2)| 00:03:01 |
| 15 | HASH GROUP BY | | 1445K| 37M| 110M| 15031 (2)| 00:03:01 |
| 16 | TABLE ACCESS FULL | TASK_WORK_HISTORY | 1445K| 37M| | 3897 (2)| 00:00:47 |
Query Block Name / Object Alias (identified by operation id):
1 - SEL$1AFB0324
2 - SEL$58A6D7F6 / from$_subquery$_005@SEL$8
3 - SEL$58A6D7F6
5 - SEL$58A6D7F6 / RESURCEWORKER@SEL$2
6 - SEL$58A6D7F6 / RESURCEWORKER@SEL$2
7 - SEL$58A6D7F6 / TASKUSESRESURCE@SEL$1
8 - SEL$58A6D7F6 / TASKUSESRESURCE@SEL$1
9 - SEL$58A6D7F6 / TASK@SEL$1
10 - SEL$58A6D7F6 / TASK@SEL$1
11 - SEL$7EBCC247 / TRW@SEL$3
12 - SEL$7EBCC247
13 - SEL$7EBCC247 / TUR@SEL$4
14 - SEL$6 / TRW_IN@SEL$5
15 - SEL$6
16 - SEL$6 / TWH@SEL$6
Predicate Information (identified by operation id):
1 - access("TRW"."RESURCE_ID"(+)="TASKUSESRESURCE"."RESURCE_ID" AND "TRW"."TASK_ID"(+)="TASK"."ID")
6 - access("RESURCEWORKER"."USER_PRINCIPAL_NAME"=U'jernej')
8 - access("TASKUSESRESURCE"."RESURCE_ID"="RESURCEWORKER"."ID")
10 - access("TASKUSESRESURCE"."TASK_ID"="TASK"."ID")
12 - access("TUR"."RESURCE_ID"(+)="TRW_IN"."RESURCE_ID" AND "TUR"."TASK_ID"(+)="TRW_IN"."TASK_ID") Jonathan, I've been to one of your workshops in Ljubljana. I'm still trying to understand everything you explained and use it, but there's much I have to learn and understand.
The way I see this query it should fist join and filter the first three tables and only then join the trw subquery. The problem with this subqrey is task_work_history table, which is accessed in very different ways in different places, so there will always be many reads to gather required data. For now, however, I'd be hapy to just bring the performance of inner join to left join... -
Left outer join functions like simple join
I created two views SCO_REQGROSSLINES_V & SCO_REQLINESCOMPLETE on Oracle requisitions base tables. Our business rules enforce the following identity: the number of gross requisition lines will always be greater than or equal to the number of requisition lines complete. (By complete I mean delivered.)
Each view has a key named DATESUBINV_KEY constructed of a transaction date and the subinventory code using this logic:
, TO_CHAR(TRUNC(transaction_date),'YYYYMMDD') || subinventory_code
On 03-SEP-2010 a user created a requisition with one line item for material from the HEAT subinventory which was not delivered. This row is retuned in the result set when I query on SCO_REQGROSSLINES_V but is NOT returned when I query on SCO_REQLINESCOMPLETE. So far so good.
When I issue either of the the following left outer joins I do not get the row for the row for the HEAT subinventory on 03-SEP-2010:
select rgl.trxn_date
, rgl.subinventory
, rgl.line_count gross_line_count
, rgl.ext_prc gross_value
, rlc.line_count lines_filled
, rlc.ext_prc lines_filled_value
from SCO_REQGROSSLINES_V rgl left outer join sco_reqlinescomplete_v rlc
ON rgl.datesubinv_key = rlc.datesubinv_key
where rgl.TRXN_DATE BETWEEN to_date('29-AUG-2010') AND to_date('04-SEP-2010')
and rlc.trxn_date BETWEEN to_date('29-AUG-2010') AND to_date('04-SEP-2010')
order by rgl.trxn_date, rgl.subinventory
select rgl.trxn_date, rgl.subinventory
, rgl.line_count gross_line_count
, rgl.ext_prc gross_value
, rlc.line_count lines_filled
, rlc.ext_prc lines_filled_value
from SCO_REQGROSSLINES_V rgl
, sco_reqlinescomplete_v rlc
where rgl.TRXN_DATE BETWEEN to_date('29-AUG-2010') AND to_date('04-SEP-2010')
and rlc.trxn_date BETWEEN to_date('29-AUG-2010') AND to_date('04-SEP-2010')
AND rgl.datesubinv_key = rlc.datesubinv_key(+)
order by rgl.trxn_date, rgl.subinventory
Question: Why would the left outer joins function as a simple join on DATESUBINV_KEY? Do keys on views function differently than keys defined in the data dictionary? If they do how can I make these keys to function like data dictionary keys?Hi,
The WHERE clause is applied after the outer join is completed. In your example, rows from rgl will be in the result set even if they have no match in rlc. In those cases, all the columns from rlc will be NULL.
Okay, so you have these rows that contain data from rgl but NULLs where the data from rlc was supposed to go. Now it's time to start the WHERE clause. You then apply conditions like this in the WHERE clause:
AND rlc.trxn_date BETWEEN ...NULL is between anything, so the row that the outer join prodeuced is rejected.
All conditions involivn columns from rlc probably need to be part of the join condition, not the WHERE clause.
For example, in you first query the FROM and WHERE clauses might be:
FROM sco_reqgrosslines_v rgl
LEFT OUTER JOIN sco_reqlinescomplete_v rlc ON rgl.datesubinv_key = rlc.datesubinv_key
AND rlc.trxn_date BETWEEN TO_DATE ( '29-AUG-2010'
, 'DD-MON-YYYY'
AND TO_DATE ( '04-SEP-2010'
, 'DD-MON-YYYY'
WHERE rgl.trxn_date BETWEEN TO_DATE ( '29-AUG-2010'
, 'DD-MON-YYYY'
AND TO_DATE ( '04-SEP-2010'
, 'DD-MON-YYYY'
)Always use (at least) two arguments when calling TO_DATE.
Conditions that only involve rgl can be in the WHERE clause, but if any conditions from rlc are in the WHERE clause, then the effect will be the same as an inner join.
There no difference between tables and views (or sub-queries) in this regard: the same thing would happen regardless of whether rgl and rlc were really tables or not. -
LEFT OUTER JOIN multiple tables - using the 9i syntax
I've always written my queries using the (+) operator for outer joins. I want to start using the new ANSI standard available in 9i. I can do it when I'm joining two tables in a simple query, but how does it work when I am joining multiple tables?
Here is an example of some SQL that works with the (+) outer join syntax. How can I convert this to use the LEFT OUTER JOIN syntax?
SELECT *
FROM audit_entry aue,
audit_table aut,
audit_statement aus,
audit_row aur,
audit_row_pkey aup1,
audit_row_pkey aup2
WHERE aue.audit_entry_id = aus.audit_entry_id
AND aut.table_name = 'TEST_AUDITING'
AND aut.table_owner = 'CLA_JOURNAL'
AND aus.audit_table_id = aut.audit_table_id
AND aur.audit_statement_id (+) = aus.audit_statement_id
AND aup1.audit_row_id (+) = aur.audit_row_id
AND aup1.pk_column_name (+) = 'TEST_AUDTING_PK_1'
AND aup2.audit_row_id (+) = aur.audit_row_id
AND aup2.pk_column_name (+) = 'TEST_AUDITING_PK_2'
I can join audit_statement to audit_entry easy enough, but then I want to join audit_table to audit_statement, how do I do that, do I start nesting the join statements?
Thanks
RichardThanks for getting back so quickly, I have tried the suggested SQL with mixed results:
SELECT COUNT(*)
FROM audit_entry aue
JOIN audit_statement aus ON aue.audit_entry_id = aus.audit_entry_id
JOIN audit_table aut ON aus.audit_table_id = aut.audit_table_id
RIGHT OUTER JOIN audit_row aur ON aur.audit_statement_id = aus.audit_statement_id
RIGHT OUTER JOIN audit_row_pkey aup1 ON aup1.audit_row_id = aur.audit_row_id
RIGHT OUTER JOIN audit_row_pkey aup2 ON aup2.audit_row_id = aur.audit_row_id
WHERE aut.table_name = 'TEST_AUDITING_TWO'
AND aut.table_owner = 'CLA_JOURNAL'
AND aup1.pk_column_name = 'TEST_AUDTING_PK_1'
AND aup2.pk_column_name = 'TEST_AUDITING_PK_2'
I had to change the order slightly, between the first two JOINs but otherwise it executed OK. My problem is, it should only return 175 rows but its returning 30625 rows. If I comment out the second reference to audit_row_pkey I get the expected result:
SELECT COUNT(*)
FROM audit_entry aue
JOIN audit_statement aus ON aue.audit_entry_id = aus.audit_entry_id
JOIN audit_table aut ON aus.audit_table_id = aut.audit_table_id
RIGHT OUTER JOIN audit_row aur ON aur.audit_statement_id = aus.audit_statement_id
RIGHT OUTER JOIN audit_row_pkey aup1 ON aup1.audit_row_id = aur.audit_row_id
--RIGHT OUTER JOIN audit_row_pkey aup2 ON aup2.audit_row_id = aur.audit_row_id
WHERE aut.table_name = 'TEST_AUDITING_TWO'
AND aut.table_owner = 'CLA_JOURNAL'
AND aup1.pk_column_name = 'TEST_AUDTING_PK_1'
--AND aup2.pk_column_name = 'TEST_AUDITING_PK_2'
It looks the same condition is being used in each case but why do I suddenly get so many rows - its joining differently somehow. It must be to do with the order, do I need to bracket the query?
Thanks again
Richard -
Not using Index when SDO_RELATE in Spatial Query is used in LEFT OUTER JOIN
I want to know for every City (Point geometry) in which Municipality (Polygon geometry) it is.
Some cities will not be covered by any municipality (as there is no data for it), so its municipality name should be blank in the result
We have 4942 cities (point geometries)
and 500 municipalities (polygon geometry)
SELECT T1.NAME as City, T2.NAME as Municipality
FROM CITY T1
LEFT OUTER JOIN MUNICIPALITY T2 ON SDO_RELATE(T1.GEOM, T2.GEOM, 'MASK=ANYINTERACT') = 'TRUE'The explain plan for this query is:
SELECT STATEMENT
FILTER
Filter Predicates
MDSYS.SDO_RTREE_RELATE(T1.GEOM, T2.GEOM, 'mask=ANYINTERACT querytype=window ') = 'TRUE'
MERGE JOIN
TABLE ACCESS CITY FULL 11
BUFFER SORT 100605
TABLE ACCESS MUNICIPALITY FULL 20So the cost is in the BUFFER (whatever that is), it takes +2000 seconds to run this, it is not using the spatial index.
And we are not getting all rows, but only the ones interacting with a municipality, e.g. 2436 rows.
But I want all rows, including the ones not interacting with any Municipality.
When we want only those cities that actually are in a municipality, I use a different query and it will use the index.
SELECT T1.NAME as City, T2.NAME as Municipality
FROM CITY T1, MUNICIPALITY T2
WHERE SDO_RELATE(T1.GEOM, T2.GEOM, 'MASK=ANYINTERACT') = 'TRUE'I get (only) 2436 rows (as expected) in 5 seconds (it is fast) and the explain plan shows it is using the spatial index.
But in this case, I am not getting any cities not inside any municipality (of course)
SELECT STATEMENT
NESTED LOOPS
TABLE ACCESS MUNICIPALITY FULL 22
TABLE ACCESS CITY BY INDEX ROWID 22
DOMAIN INDEX CITY_SDX 0
Access Predicates
MDSYS.SDO_RTREE_RELATE(T1.GEOM, T2.GEOM, 'mask=ANYINTERACT querytype=window ') = 'TRUE'I always thought a LEFT OUTER JOIN would return all rows from the Table, whatever happens in the next,
but it seems the query has been rewritten so that it is now using a Filter Predicate in the end, which filters those geometries having no interaction.
As an example I also do thing alphanumerically, I do get 4942 rows, including the ones which have no Municipality name.
In this case the names must match, so its only for testing if the LEFT OUTER JOIN returns stuff correctly, which it does in this case.
SELECT T1.NAME as City, T2.NAME as Municipality
FROM CITY T1
LEFT OUTER JOIN MUNICIPALITY T2 ON T1.NAME = T2.NAMEIs this an Oracle Spatial bug, e.g. not return 4942 rows, but only 2436 rows on the first query?
Note all tests performed on Oracle 11g R2 (11.2.0.1.0)Patrick,
Even so, your geoms in the relate were the wrong way around.
Also, I don't recall you saying (or showing) that you wanted the municipality geometry returned. Still,
no matter, easy to do.
Here are some additional suggestions. I don't have your data so I have had to use some of my own.
set serveroutput on timing on autotrace on
SELECT T1.SPECIES as City,
(SELECT T2.ADMIN_NAME FROM AUSTRALIAN_STATES T2 WHERE SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE') as Municipality,
(SELECT T2.GEOM FROM AUSTRALIAN_STATES T2 WHERE SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE') as geom
FROM GUTDATA T1;
762 rows selected
Elapsed: 00:00:21.656
Plan hash value: 2160035213
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 762 | 49530 | 5 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| AUSTRALIAN_STATES | 1 | 115 | 0 (0)| 00:00:01 |
|* 2 | DOMAIN INDEX | AUSTRALIAN_STATES_GEOM_SPX | | | 0 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| AUSTRALIAN_STATES | 1 | 115 | 0 (0)| 00:00:01 |
|* 4 | DOMAIN INDEX | AUSTRALIAN_STATES_GEOM_SPX | | | 0 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | GUTDATA | 762 | 49530 | 5 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - access("MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"(:B1,10000,0.5,'UNIT=M'))='TRUE')
4 - access("MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"(:B1,10000,0.5,'UNIT=M'))='TRUE')
Statistics
7 user calls
24576 physical read total bytes
0 physical write total bytes
0 spare statistic 3
0 commit cleanout failures: cannot pin
0 TBS Extension: bytes extended
0 total number of times SMON posted
0 SMON posted for undo segment recovery
0 SMON posted for dropping temp segment
0 segment prealloc tasksThe above can look messy as you add more (SELECT ...) attributes, but is is fast (though can't use in Materialized Views).
/* The set of all cities not in municipalities */
SELECT T1.SPECIES as City,
cast(null as varchar2(42)) as municipality,
cast(null as sdo_geometry) as geom
FROM GUTDATA T1
WHERE NOT EXISTS (SELECT 1
FROM AUSTRALIAN_STATES T2
WHERE SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE')
UNION ALL
/* The set of all cities in municipalities */
SELECT T1.SPECIES as City,
T2.ADMIN_NAME as Municipality,
T2.GEOM as geom
FROM GUTDATA T1
INNER JOIN
AUSTRALIAN_STATES T2 ON (SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE');
762 rows selected
Elapsed: 00:00:59.953
Plan hash value: 2854682795
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 99 | 13450 | 38 (87)| 00:00:01 |
| 1 | UNION-ALL | | | | | |
|* 2 | FILTER | | | | | |
| 3 | TABLE ACCESS FULL| GUTDATA | 762 | 49530 | 5 (0)| 00:00:01 |
|* 4 | DOMAIN INDEX | AUSTRALIAN_STATES_GEOM_SPX | | | 0 (0)| 00:00:01 |
| 5 | NESTED LOOPS | | 61 | 10980 | 33 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL| AUSTRALIAN_STATES | 8 | 920 | 3 (0)| 00:00:01 |
|* 7 | TABLE ACCESS FULL| GUTDATA | 8 | 520 | 4 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - filter( NOT EXISTS (SELECT 0 FROM "AUSTRALIAN_STATES" "T2" WHERE "MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"(:B1,10000,0.5,'UNIT=M'))='TRUE'))
4 - access("MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"(:B1,10000,0.5,'UNIT=M'))='TRUE')
7 - filter("MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"("T1"."GEOM",10000,0.5,'UNIT=M'))='TRUE')
Statistics
7 user calls
131072 physical read total bytes
0 physical write total bytes
0 spare statistic 3
0 commit cleanout failures: cannot pin
0 TBS Extension: bytes extended
0 total number of times SMON posted
0 SMON posted for undo segment recovery
0 SMON posted for dropping temp segment
0 segment prealloc tasksMuch slower but Materialized View friendly.
This one is a bit more "natural" but still slower than the first.
set serveroutput on timing on autotrace on
/* The set of all cities in municipalities */
WITH municipal_cities As (
SELECT T1.ID as City,
T2.ADMIN_NAME as Municipality,
T2.GEOM as geom
FROM GUTDATA T1
INNER JOIN
AUSTRALIAN_STATES T2 ON (SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE')
SELECT T1.ID as City,
T2.Municipality as Municipality,
T2.GEOM as geom
FROM GUTDATA T1
LEFT OUTER JOIN
municipal_cities T2
ON (T2.CITY = T1.ID);
762 rows selected
Elapsed: 00:00:50.228
Plan hash value: 745978991
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 762 | 44196 | 36 (3)| 00:00:01 |
|* 1 | HASH JOIN RIGHT OUTER| | 762 | 44196 | 36 (3)| 00:00:01 |
| 2 | VIEW | | 61 | 3294 | 33 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | 61 | 10980 | 33 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | AUSTRALIAN_STATES | 8 | 920 | 3 (0)| 00:00:01 |
|* 5 | TABLE ACCESS FULL | GUTDATA | 8 | 520 | 4 (0)| 00:00:01 |
| 6 | INDEX FAST FULL SCAN| GUTDATA_ID_PK | 762 | 3048 | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("T2"."CITY"(+)="T1"."ID")
5 - filter("MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"("T1"."GEOM",10000,0.5,'UNIT=M'))='TRUE')
Statistics
7 user calls
49152 physical read total bytes
0 physical write total bytes
0 spare statistic 3
0 commit cleanout failures: cannot pin
0 TBS Extension: bytes extended
0 total number of times SMON posted
0 SMON posted for undo segment recovery
0 SMON posted for dropping temp segment
0 segment prealloc tasksFinally, the Pièce de résistance: trick the LEFT OUTER JOIN operator...
set serveroutput on timing on autotrace on
SELECT T1.SPECIES as City,
T2.ADMIN_NAME as Municipality,
T2.GEOM as geom
FROM GUTDATA T1
LEFT OUTER JOIN
AUSTRALIAN_STATES T2
ON (t2.admin_name = to_char(t1.ID) OR
SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE');
762 rows selected
Elapsed: 00:00:50.273
Plan hash value: 158854308
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 762 | 92964 | 2294 (1)| 00:00:28 |
| 1 | NESTED LOOPS OUTER | | 762 | 92964 | 2294 (1)| 00:00:28 |
| 2 | TABLE ACCESS FULL | GUTDATA | 762 | 49530 | 5 (0)| 00:00:01 |
| 3 | VIEW | | 1 | 57 | 3 (0)| 00:00:01 |
|* 4 | TABLE ACCESS FULL| AUSTRALIAN_STATES | 1 | 115 | 3 (0)| 00:00:01 |
Predicate Information (identified by operation id):
4 - filter("T2"."ADMIN_NAME"=TO_CHAR("T1"."ID") OR
"MDSYS"."SDO_ANYINTERACT"("T2"."GEOM","SDO_GEOM"."SDO_BUFFER"("T1"."GEOM",10000,0.5,'UNIT=M'))='TRUE')
Statistics
7 user calls
0 physical read total bytes
0 physical write total bytes
0 spare statistic 3
0 commit cleanout failures: cannot pin
0 TBS Extension: bytes extended
0 total number of times SMON posted
0 SMON posted for undo segment recovery
0 SMON posted for dropping temp segment
0 segment prealloc tasksTry these combinations to see what works for you.
Interestingly, for me, the following returns absolutely nothing.
SELECT T1.SPECIES as City,
T2.ADMIN_NAME as Municipality
FROM GUTDATA T1
LEFT OUTER JOIN
AUSTRALIAN_STATES T2
ON (SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE')
MINUS
SELECT T1.SPECIES as City,
T2.ADMIN_NAME as Municipality
FROM GUTDATA T1
LEFT OUTER JOIN
AUSTRALIAN_STATES T2
ON (t2.admin_name = to_char(t1.ID) OR
SDO_ANYINTERACT(T2.GEOM, SDO_GEOM.SDO_BUFFER(T1.GEOM,10000,0.5,'UNIT=M')) = 'TRUE');(I leave it to you to see if you can see why as the LEFT OUTER JOIN seems to be working correctly for me but I am not going to dedicate time to detailed checking of results.)
Note all tests performed on Oracle 11g R2 (11.2.0.1.0)
If you get the answer you want: mark the post as answered to assign points.
regards
Simon -
How to do left outer join in one-one mapping
I tried to do a left outer join between two tables. I specified
kodo.jdbc.DBDictionary: JoinSyntax=sql92 in kodo.properties. I used
ref-join-type="outer" in the package.mapping. However, I still see Kodo is
translating my queries using inner join. How can I force kodo to use outer
join (or maybe even to use left outer join) when translating my queries?
Thanks.Kodo will automatically use an outer join when eager-fetching a to-one
relation (unless you have set null-value="exception" on the field, in
which case Kodo knows it can use an inner join). There is no need to set
the ref-join type (in fact, that is only for when the foreign key
columns are in a joined table).
When you place criteria on a relation in a query, though, the relation
must exist to satisfy the query. For example, in the filter:
"relation.x == y"
The "relation" field must hold a related object to satisfy the
expression, just as in Java.
If you want the "relation" field to optionally be null, then write your
filter exactly as you would in Java:
"relation == null || relation.x == y"
Kodo will correctly use an outer join in this case because the filter
can be satisfied even when no related object exists. -
Query Of Queries : Error When Trying To Fake Left Outer Join
Hi there
I am trying to replicate a left outer join, combining two query of queries using a method I located here
However, I keep getting an error message..
Here is the code I am using....
<cfquery dbtype="query" name="qry">
SELECT *
FROM returnQry, returnQry2
WHERE returnQry.mediumImage = returnQry2.mediumImage
ORDER BY returnQry.name
</cfquery>
<cfquery name="returnQry3" dbtype="#application.mx#">
SELECT *
FROM trackmeanings AS t
</cfquery>
<cfquery dbtype="query" name="endQry">
SELECT name,nameRcd,mediumImage, COUNT(sMessage) AS comments
FROM qry, returnQry3
WHERE qry.name = returnQry3.sNameTrack
UNION
SELECT name,nameRcd,mediumImage, COUNT(sMessage) AS comments
FROM qry, returnQry3
WHERE #qry.name# NOT IN (#QuotedValueList(returnQry3.sNameTrack)#)
GROUP BY name,nameRcd,mediumImage
</cfquery>
When I try to use the query output in a page, i get the error message "Incorrect conditional expression, Expected one of [like|null|between|in|comparison] condition"
Would anyone have any ideas?
Many thanksActually , spoke a little too soon, my query now seems to be outputting duplicates when the value is found on both sides of the union, my group by clause doesnt seem to be eliminating them like it usually does.
My SELECT code now reads
<cfquery dbtype="query" name="endQry">
SELECT name,nameRcd,mediumImage, COUNT(sMessage) AS comments
FROM qry, returnQry3
WHERE qry.name = returnQry3.sNameTrack
GROUP BY name,nameRcd,mediumImage
UNION
SELECT name,nameRcd,mediumImage, 0 AS comments
FROM qry
WHERE qry.name NOT IN (<cfqueryparam
value="#returnQry3.sNameTrack#"
cfsqltype="cf_sql_varchar"
list="yes"
/>)
GROUP BY name,nameRcd,mediumImage
ORDER BY name DESC
</cfquery>
and my ouput...is producing duplicates
<cfoutput query="rc.qryTopTracks" group="name">
#rc.qryTopTracks.name#
</cfoutput>
Would you have any idea of how to eliminate them here? Thanks -
Hi Experts,
I am facing a problem with left outer join query. Am using one standard table and ztable for this join. My problem is values are not extracted from the Ztable.
Query:
SELECT b~lifnr b~belnr b~gjahr b~xblnr b~shkzg b~blart b~zfbdt b~budat b~wrbtr
b~wskto b~zlspr s~EXTRACT_STATUS s~maturity_date FROM bsik AS b
LEFT OUTER JOIN zprm_rvne_sapdoc AS s
ON s~belnr EQ b~belnr
AND s~gjahr EQ b~gjahr
INTO CORRESPONDING FIELDS OF TABLE it_join
WHERE b~zlsch = p_zlsch
AND b~xblnr IN so_invno
ORDER BY b~lifnr b~xblnr.
I have all entries of BSIK table in Ztable with extract status as Y but this query is not fetching extract status and maturity date of ztable so it is blank in the internal table.
Need solution.
Regards
Sridevi SHi,
see the sample wiki for writing the Left outer join
http://wiki.sdn.sap.com/wiki/display/Snippets/EmployeeInfotype0000to9999ChangeHistory
Specifying Two or More Database Tables as a Left Outer Join
The left outer join, on the other hand, reads lines from the left-hand database table or join even if there is no corresponding line in the right-hand table.
SELECT...
FROM <tab> LEFT [OUTER] JOIN <dbtab> [AS <alias>] ON <cond>
<options>
<tab> and <dbtab> are subject to the same rules and conditions as in an inner join. The OUTER addition is optional. The tables are linked in the same way as the inner join with the one exception that all lines selected from <tab> are included in the final selection. If <dbtab> does not contain any lines that meet the condition <cond>, the system includes a single line in the selection whose columns from <dbtab> are filled with null values.
In the left outer join, more restrictions apply to the condition <cond> than in the inner join. In addition to the above restrictions:
EQ or = is the only permitted relational operator.
There must be at least one comparison between columns from <tab> and <dbtab>.
The WHERE clause may not contain any comparisons with columns from <dbtab>. All comparisons using columns from <dbtab> must appear in the condition <cond>.
If we have two tables named stud1,stud2 with the following data
Stud1: id Name stud2: id Name
1 xxx 1 aaa
2 yyy 2 bbb
3 zzz 4 ccc
4 www 6 ddd
When we use Left Outer Join we get the output as:
1 aaa
2 bbb
3 <Null>
4 ccc
When we use Right Outer Join we get the output as:
1 aaa
2 bbb
4 ccc
<Null> ddd
When we use Full Outer Join we get the output as:
1 aaa
2 bbb
3 <Null>
4 ccc
<Null> ddd
Prabhudas -
Oracle 8i -multiple LEFT OUTER JOIN
Hi,
I have to convert some stored procedure from Sql Server to Oracle 8i where I have multiple LEFT OUTER JOIN on a table. Because Oracle 8i accept only one outer join on a table how can I convert this:
select a.id, b.id
from test as a LEFT JOIN test1 b ON a.id(+)=b.id
and a.display(+)=b.display
and a.name(+)='Done';
Thanks.FROM test a LEFT JOIN test1 b ON b.key = a.keyis equivalent to
FROM test a, test1 b WHERE b.key(+) = a.keyThere is a restriction (when using the "(+)" syntax) that a table may be outer-joined to at most one other table, but that does not prevent you from having multiple join conditions between those two tables.
From your example I'm not sure whether you need this:
SELECT a.id, b.id
FROM test a
, test1 b
WHERE a.name = 'Done'
AND b.id (+)= a.id
AND b.display (+)= a.display;or this:
SELECT a.id, b.id
FROM test1 b
, test a
WHERE a.id (+)= b.id
AND a.display (+)= b.display;
WHERE a.name (+)= 'Done'; -
LEFT OUTER JOIN not working as expected
I'm testing a query from the portal. I've got two inputs:
products
{"ProductKey":1,"ProductAlternateKey":"abc","Color":"Red"},
{"ProductKey":2,"ProductAlternateKey":"def","Color":"Blue"},
{"ProductKey":3,"ProductAlternateKey":"ghi","Color":"Blue"}
And temperatures:
{"DeviceId":1,"Temperature":99},
{"DeviceId":2,"Temperature":90},
{"DeviceId":2,"Temperature":99},
{"DeviceId":3,"Temperature":50},
{"DeviceId":4,"Temperature":32}
When I test a query with an (inner) join, I get two rows, one for Red and one for Blue as expected. However, when I change to a LEFT OUTER JOIN, I would expect to get three rows... one for Red, one for Blue, and one for NULL color. However, I only get one
row with a NULL color. Here's the query. Is this a bug or am I misunderstanding?
SELECT DateAdd(second,-5,System.TimeStamp) as WinStartTime
, system.TimeStamp as WinEndTime
, b.Color
, Avg(r.Temperature) as AvgTemperature
, Count(*) as EventCount
FROM temperatures r
LEFT OUTER JOIN products b ON r.DeviceId = b.ProductKey and DATEDIFF(hour,r,b) BETWEEN -6 AND 6
GROUP BY TumblingWindow(second, 5), b.Color
(Please excuse the contrived example, the lack of timestamps, and the 12 hour window... just testing.)
http://artisconsulting.com/Blogs/GregGallowayHi Greg,
Thank you for raising this issue.
We have deployed a fix today that corrects LEFT OUTER JOIN behavior on the in-browser query testing experience.
Can you please confirm that the above query and input sources work for you?
Thanks!
Ziv. -
Left Outer Joining multiple tables to one source table FAILS with VLD-1511
Hi all,
Is it me, or is OWB unable to handle left outer joining 1 source table to multiple other tables?
I want to load a fact table so I have 1 source table with measures. This table must be outer joined to some dimensions that have their FK in the fact table.
The SQL statement would look like this (and is perfectly valid):
select ...
from input, dim1, dim2
where input.c1 = dim1.c1(+)
and input.c2 = dim2.c2(+);
I put the where clause in the joiner operator and validate, but that gives me message VLD-1511: A table may be outer joined to at most one other table.
Even splitting this up into one outer join per joiner still gives this message.
A search and look around on the forum and on metalink shows there are related issues (like bug 3334035). Seemingly creating a view is the work-around to use.....? (ie downgrading owb to a simple gui tool) }-;
Have other people experienced this problem of not being able to outer join one input table to multiple other tables?
Thanks,
EdI have had some feedback from Oracle. It turns out this has to do with 2 issues. Below I have pasted the text that Support gave me:
<---------- START QUOTE ---------->
RESEARCH
=========
Bug 3437036 KEY LOOKUP DOES NOT DETECT ORA-1417 IN VALIDATE/GENERATE STEP
Unpublished Bug 4211684 FORWARD PORT OF BUG 3437036
shows:
Some more development has been completed when this bug is fixed in Paris.
The following are the details:
1. If the join condition contains a full outer join such as
tab1.c (+) = tab2.c (+) and tab2.c (+) = tab3.c
then the new validations implemented for this bug do not apply since
in OWB, full outer join triggers generation of joins in ANSI syntax.
ANSI syntax does not have the original problem the base bug of this
bug reported.
2. If the join condition does not contain any full outer join condition,
then the join is generated in Oracle join syntax, which is subject two
several restrictions. The fix to this bug check two of the restrictions.
3. The first restriction in Oracle syntax is that the outer join operator
"(+)" can only directly be attached to a column name. If you attach it
to an expression, such as the following:
(tab1.c + 1) (+) = tab2.c
Then there will be an ORA-936 error at the time of mapping deployment.
For this case, I have added a validation message VLD-1512 to error out
this situation.
4. The second restriction in Oracle syntax is that a table can only be
outer joined to exactly one other table.
For example, this is an invalid join in Oracle syntax:
tab1.c (+) = tab2.c and tab1.d (+) = tab3.d
because tab1 is left outer joined to tab2 and tab3.
But note that the following is still valid in Oracle syntax:
tab1.c (+) = tab2.c and tab1.d = tab3.d (+)
because tab1 is left outer joined to tab2 and right outer joined to tab3.
So this latter case does not violate the restriction that "same oj" to
more than 1 table is not allowed.
If same oj to more than 1 table is specified in a join condition,
VLD-1511 will be issued, and the map is made invalid.
<---------- END QUOTE ---------->
OWB does a partial validation, ie not all access paths are (can be) checked. A full check is only done by the database itself. So some scenarios (like checking whether multiple tables are outer joined the correct way) are not checked, and in this case are flagged with an error (even though it is actually a correct scenario).
Seemingly this was not flagged with an error in earlier versions of OWB, so beware, OWB behaviour may change when upgrading...
Alternative solutions are (1) using key lookups, (2) using a view with all outer joins in there, (3) using intermediate result tables between the joins.
Hope this info helps some people prevent spending too much time on a false error message,
Ed
Maybe you are looking for
-
How can I print without connection to internet?
My internet connection is very poor. It's often down. How can I print from mi mobile device to the printer that is wired connected? With iprint photo nothing was needed.
-
How to pass varchar2 in as parameter in SP
I have a sp which takes dname as parameter (see below code), I tried 'ACCOUNTING', ''ACCOUNTING'' (2 single 's) and "ACCOUNTING" none of them worked. Could you tell me how to pass this in ( from pl/SQL and Java)? This is my code: CREATE OR REPLACE PA
-
Error on export from a 1.5 version and import to a 1.6 version
I am exporting a 1.5 version of an application to the 1.6 version on the Oracle Workspace and I get the following error: ORA-20001: GET_BLOCK Error. ORA-20001: Execution of the statement was unsuccessful. ORA-00001: unique constraint (FLOWS_010601.WW
-
I would like to know how I can insert a generic component (like a Canvas whit image and label) in a List visual component. Is it possible or there's another way for to do a list of component ?
-
How to display all the files name in same folder inside a JTable?
Currently i am doing an LAN P2P application (similar to KazAa) which is have a function to search files and list out files name after searched found. I am planning to list all the searched file names in JTable. I am having problem to list the files n