Outer join OJ syntax with JDBC drivers
Hello,
I'm facing a problem with CrystalReports 2008 and jdbc connection.
Crystal genrates OJ syntax (as below) which cannot be interpreted by the Database.
SELECT "T1"."T1D", "T2"."T2D", "T3"."T3D"
FROM {oj ("PUBLIC"."PUBLIC"."T3" "T3" LEFT OUTER JOIN "PUBLIC"."PUBLIC"."T2" "T2" ON "T3"."T2K"="T2"."T2K") LEFT OUTER JOIN "PUBLIC"."PUBLIC"."T1" "T1" ON "T2"."T1K"="T1"."T1K"}
Prensently my database is HSQLDB.
After browsing several post about ODBC, I tried to change the registry, introducing a new key
HKEY_CURRENT_USER\Software\Business Objects\Suite 12.0\Crystal Reports\DatabaseOptions\NoOuterJoinEscSeq=myodbc3,hsqldb
It did not change anything.
Now, I suppose Crystal queries the database driver for its capabilities.
This is done by a DatabaseMetaData object which implements several methods.
In case of hsqldb, here is what the driver answers:
public boolean supportsMinimumSQLGrammar() throws SQLException {
return false;
public boolean supportsCoreSQLGrammar() throws SQLException {
return true;
public boolean supportsExtendedSQLGrammar() throws SQLException {
return false;
public boolean supportsANSI92EntryLevelSQL() throws SQLException {
return false;
public boolean supportsANSI92IntermediateSQL() throws SQLException {
return false;
public boolean supportsANSI92FullSQL() throws SQLException {
return false;
public boolean supportsIntegrityEnhancementFacility() throws SQLException {
return true;
public boolean supportsOuterJoins() throws SQLException {
return true;
public boolean supportsFullOuterJoins() throws SQLException {
return false;
public boolean supportsLimitedOuterJoins() throws SQLException {
return true;
How can I tell Crystal to stop using the OJ syntax ?
Thank you and kind regards.
Alain
Hi Alaine,
You are correct, CR does query the driver to get what it requires to use for outer join syntax. The registry key will not work for this driver. It's the driver meta layer telling CR to use the oj syntax and is dependent on the driver being configured.
Not sure if you can but start by trying to alter these settings if you can:
public boolean supportsOuterJoins() throws SQLException {
return true;
public boolean supportsFullOuterJoins() throws SQLException {
return false;
I would think both should be reversed, true to false and false to true.
Before you do that though go to our download page and install Service Pack 2, it may by a CR issue and the patch may have fixed the problem.
If it doesn't I suggest asking this on the HSQLDB forum to see how to alter those option. CR follows the JDBC Type 4 Standards. You may want to see if Sun has a HSQLDB JDBC driver also.
Thank you
Don
Similar Messages
-
Left outer join 3 tables with where-statement
Hi folks,
I hope you can understand (and maybe solve) my problem.
Generally I try to left outer join three tables. The third table is used for a WHERE-statement.
The three table structures are the following:
table 1 (user)
user1 | key
table 2 (detail)
key | ID
table 3 (header)
ID | user2
...and I want to achieve the following structure (as example filled with data):
user | key | ID
|-----|----
xy | a | 001
xy | b | #
z | b | #
The clue ist the usage of the third table. I need the table to set user1 and user2 equal (WHERE) but there are two problems:
1) Obviously I can't left outer join two tables with each other. In this case I already used the 'key' of table 1 to join it with the 'key' of table 2. So I can't left outer join the 'ID' of table 2 with the 'ID' of table 3. Error message that I can only left outer join a table once. Any proposals?
2) I have to include a WHERE to equal user1 with user2. But I am not allowed to use the user2 from table 3 because of the left outer join.
I tried this coding:
SELECT auser1 akey b~id INTO TABLE itab FROM ( table1 AS a
LEFT OUTER JOIN table2 AS b ON akey = bkey )
LEFT OUTER JOIN table3 AS c ON bID = cID )
WHERE auser1 = cuser2.
I would really appreciate your help.
Regards
MrclSpdlIF you want to join a DB table with an internal table, you need to use the 'FOR ALL ENTRIES' statement.
select dbfields
into table itab2
from dbtab
for all entries in itab
where dbfield1 = itab-field1.
This will get you a second internal table with all the corresponding data for the first selection. You can then join them with a loop through the first table and a read table on the second table (for 1 - 1 relation) or a nested loop statement on both tables (for 1 - N relation). Make itab a hashed table when using read table with key, use a sorted table if you need to loop without key access.
Regards,
Freek -
Haven't seen a solution to this on the forum or in the docs. My last post timed out with no responses, but I still don't know if I have a possible solution.
I've got 2 objects, Task and Role, that are linked in a M-M relationship.
My tables are:
T_TASKS
T_TASKSROLES
T_ROLES
I am querying T_TASKS and joining on T_TASKSROLES and T_ROLES, but I need to use an outer join because not all Tasks have a Role in T_TASKSROLES.
In SQL Server, my FROM clause SHOULD look like this:
FROM (T_TASKSROLES t2 LEFT OUTER JOIN T_TASKS t1 ON t1.ID = t2.TASKID) LEFT OUTER JOIN T_ROLES t0 ON t0.ID = t2.ROLEID
however, if I use eb.anyOfAllowingNone(_roles) in my ExpressionBuilder. TopLink creates a LEFT OUTER JOIN clause that looks like this:
FROM T_ROLES t0 LEFT OUTER JOIN T_TASKS t1 ON((t0.ID = T_TASKSROLES.ROLEID) AND (t1.ID = T_TASKSROLES.TASKID))
I can see the logic in how it builds this clause. But, it doesn't parse in SQL Server.
Is there a way to effect how TopLink generates the FROM clause for outer joins? I mean, I understand how to use the XXXPlatform.java source files and can change whether to use OuterJoin in the WHERE clause or not. But, I can't see anything in the platform class that would allow me to figure this out.
I realize I could write SQL manually, but is there a way to do this so that the same code would work on SQL Server, Oracle, and Sybase (assuming the DatabaseLogin is configured appropriately)?
It just seems like LEFT OUTER JOIN when joining M-M relationships isn't generating proper SQL. Is the TopLink SQL SQL92-compliant?
I should add that I have tried to change SQLServerPlatform to have shouldPrintOuterJoinInWhereClause() return "true". This embeds a "=*" in the join conditions in the WHERE clause.
SQL Server 2000 still supports this syntax, but the "=*" isn't ALWAYS the correct operator. It is important to put the "*" on the correct side of the expression. TopLink always prints "=*", but the operators are not always in the correct order. So, it tries to create a "left join" on the wrong table.
So my other question, is it possible to force TopLink to remember to put the outer join table in the RIGHT SIDE?
NateThe workaround is actually more complicated than that, and it can't be fixed by changing only the operator.
In the queries you listed, the only difference is which side of the "AND" the expressions appear on.
Change "(t2.rightid (+)= t1.rightid)" to "(t1.rightid (+)= t2.rightid)" and I'm guessing (although not sure because I am testing with SQL Server at the moment), that you'll get a similar query error as I did.
The bug here is that the default M-M selection criteria creates "reltable = table1 AND table2 = reltable". There is no operator that can satisfy this expression.
So, the fix that I made, for all of my M-M Mappings was to set the SelectionCriteria manually using the following Expression (returned from this method):
// This puts M-M relationship tables on the same side of expressions so that OUTER JOINS can be supported.
private Expression getSameSideExpression() {
// target side
Expression selectionCriteria = null;
Enumeration e2 = getTargetKeyFields().elements();
Enumeration e = getTargetRelationKeyFields().elements();
ExpressionBuilder eb = new ExpressionBuilder();
Expression relTableExp = null;
while(e2.hasMoreElements()) {
DatabaseField df = (DatabaseField) e.nextElement();
DatabaseField df2 = (DatabaseField) e2.nextElement();
if(relTableExp == null){
relTableExp = eb.getTable(df.getTable());
Expression targetFieldExp = eb.getField(df2);
Expression relFieldExp = relTableExp.getField(df);
Expression joinExp = relFieldExp.equal(targetFieldExp);
if(selectionCriteria == null)
selectionCriteria = joinExp;
else
selectionCriteria = joinExp.and(selectionCriteria);
// source side
e = getSourceRelationKeyFields().elements();
e2 = getSourceKeyFields().elements();
while(e.hasMoreElements()) {
DatabaseField df = (DatabaseField) e.nextElement();
DatabaseField df2 = (DatabaseField) e2.nextElement();
Expression relFieldExp = relTableExp.getField(df);
Expression sourceFieldExp = eb.getParameter(df2);
Expression joinExp = relFieldExp.equal(sourceFieldExp);
if(selectionCriteria == null)
selectionCriteria = joinExp;
else
selectionCriteria = joinExp.and(selectionCriteria);
return selectionCriteria;
This changes the M-M Selection Criteria to "table1 = reltable AND table2 = reltable". Now that this is consistent, using the WHERE clause for my joins in SQL Server is possible.
If you can think of any other problems this change may have, please let me know.
Thanks for the help.
Nate -
Oracle.sql.* with JDBC drivers 8.0.5
the oracle.sql package is not included in my JDBC driver file classes111.zip given for oracle data server version 8.0.5.
I would like to use the oracle STRUCT and ARRAY type for calling PL/SQL stored procedures taking STRUCT objects in arguments.
Are the JDBC drivers 8.1.* compatible with the oracle data server 8.0.5 (if I only use the STRUCT or ARRAY types)? Is it a way for passing ARRAY of VARCHAR2 values to PL/SQL stored procedure with the oracle 8.0.5 JDBC driver?
thanksUnfortunately, these classes (oracle.sql.STRUCT and oracle.sql.ARRAY) are not compatible to 8.0 database. There is server format changes between 8.1 and 8.0, and JDBC driver only supports the 8.1 format.
Please upgrade your database to 8i. -
Outer join on query with OR clause
hi all, i am having problem outerjoining a query with or clause
here is my data
WITH table1 AS
SELECT 'test' txt1, 'pak' txt2, 'ced' txt3, 'su' txt4 FROM dual UNION ALL
SELECT null txt1, 'pak' txt2, 'ced2' txt3, 'su2' txt4 FROM dual UNION ALL
SELECT null txt1, NULL txt2, 'ced3' txt3, 'su3' txt4 FROM dual UNION ALL
SELECT null txt1, NULL txt2, null txt3, 'su3' txt4 FROM dual UNION ALL
SELECT 'text5' txt1, NULL txt2, null txt3, 'su3' txt4 FROM dual UNION ALL
SELECT null txt1, NULL txt2, null txt3, null txt4 FROM dual
,table2 AS
SELECT 111 pid, 'test' txt1, 'pak4' txt2, 'ced' txt3, 'su' txt4 FROM dual UNION ALL
SELECT 222 pid, 'test1' txt1, 'pak' txt2, 'ced2' txt3, 'su2' txt4 FROM dual UNION ALL
SELECT 333 pid, 'test2' txt1, 'pak3' txt2, 'ced3' txt3, 'su4' txt4 FROM dual UNION ALL
SELECT 444 pid, 'test2' txt1, 'pak3' txt2, 'ced4' txt3, 'su3' txt4 FROM dual
SELECT b.pid, a.*
from table1 a, table2 b
WHERE (a.txt1 = b.txt1 OR
a.txt1 IS NULL AND a.txt2=b.txt2 OR
Nvl(a.txt2, a.txt1) IS NULL AND a.txt3 = b.txt3 OR
Nvl(a.txt2, a.txt1) IS NULL AND a.txt3 IS NULL AND a.txt4 = b.txt4
) as you can see i am joining table1 and table 2. i am joining with txt1, if txt1 is null then join by txt2, if null then join by txt3 and so on.
the code above product this output
PID TXT1 TXT2 TXT3 TXT4
=== ==== === ==== ====
111 test pak ced su
222 pak ced2 su2
333 ced3 su3
444 su3this output is partially correct. only 4 rows were display and two was left out
SELECT 'text5' txt1, NULL txt2, null txt3, 'su3' txt4 FROM dual UNION ALL
SELECT null txt1, NULL txt2, null txt3, null txt4 FROM dual i tried using outer join but oracle complain that i cannot use outerjoin with OR clause.
can someone help modify my query to display the output below ?
PID TXT1 TXT2 TXT3 TXT4
=== ==== === ==== ====
111 test pak ced su
222 pak ced2 su2
333 ced3 su3
444 su3
NULL NULL NULL NULL NULL
test5Not sure you can do it with the Oracle style outer joins, but wioth ANSI style joins it is simple, actually exactly as you had it.
SQL> set null null;
SQL> WITH table1 AS (
2 SELECT 'test' txt1, 'pak' txt2, 'ced' txt3, 'su' txt4 FROM dual UNION ALL
3 SELECT null txt1, 'pak' txt2, 'ced2' txt3, 'su2' txt4 FROM dual UNION ALL
4 SELECT null txt1, NULL txt2, 'ced3' txt3, 'su3' txt4 FROM dual UNION ALL
5 SELECT null txt1, NULL txt2, null txt3, 'su3' txt4 FROM dual UNION ALL
6 SELECT 'text5' txt1, NULL txt2, null txt3, 'su3' txt4 FROM dual UNION ALL
7 SELECT null txt1, NULL txt2, null txt3, null txt4 FROM dual),
8 table2 AS (
9 SELECT 111 pid, 'test' txt1, 'pak4' txt2, 'ced' txt3, 'su' txt4 FROM dual UNION ALL
10 SELECT 222 pid, 'test1' txt1, 'pak' txt2, 'ced2' txt3, 'su2' txt4 FROM dual UNION ALL
11 SELECT 333 pid, 'test2' txt1, 'pak3' txt2, 'ced3' txt3, 'su4' txt4 FROM dual UNION ALL
12 SELECT 444 pid, 'test2' txt1, 'pak3' txt2, 'ced4' txt3, 'su3' txt4 FROM dual)
13 SELECT b.pid, a.*
14 from table1 a
15 LEFT JOIN table2 b
16 ON (a.txt1 = b.txt1 OR
17 a.txt1 IS NULL AND a.txt2=b.txt2 OR
18 Nvl(a.txt2, a.txt1) IS NULL AND a.txt3 = b.txt3 OR
19 Nvl(a.txt2, a.txt1) IS NULL AND a.txt3 IS NULL AND a.txt4 = b.txt4);
PID TXT1 TXT2 TXT3 TXT4
111 test pak ced su
222 null pak ced2 su2
333 null null ced3 su3
444 null null null su3
null text5 null null su3
null null null null nullJohn -
Outer join two tables with two keys
Hi,
I have a question regard outer join,
I have table A (Aid, ADesc), Table B(Bid, Bdesc), and Table C (Aid, Bid, Cdesc)
There is data in Table A and B, but Table C is empty
I want to outer join C with A and B with below query
select ADesc,Bdesc, Cdest
from A, B, C
where A.Aid=C.Aid(+) and B.Bid(+)=C.Bid
and A.Aid='XXX' and B.Bid(+)='ZZZ'
The query result show only data in column Adesc , but column BDesc is empty even though there are some data in table B.
How should the query been modified to correctly show ADESC and Bdesc.
Thanks
VincentGuess the below should work:
Case when records are available in Table C:
with a as
(select 'XXX' aid, 'adesc' adesc from dual),
b as
(select 'ZZZ' bid, 'bdesc' bdesc from dual),
c as
(select 'XXX' aid, 'ZZZ' bid, 'cdest' cdest from dual where 1 = 1)
select ADesc,Bdesc, C1.Cdest
from
A LEFT OUTER JOIN C c1 ON (A.AID = C1.AID AND A.AID = 'XXX'),
B LEFT OUTER JOIN C C2 ON (B.BID = C2.BID AND B.BID = 'ZZZ');
Output:
"ADESC" "BDESC" "CDEST"
"adesc" "bdesc" "cdest"Case when table C is empty:
with a as
(select 'XXX' aid, 'adesc' adesc from dual),
b as
(select 'ZZZ' bid, 'bdesc' bdesc from dual),
c as
(select 'XXX' aid, 'ZZZ' bid, 'cdest' cdest from dual where 1 = 2)
select ADesc,Bdesc, C1.Cdest
from
A LEFT OUTER JOIN C c1 ON (A.AID = C1.AID AND A.AID = 'XXX'),
B LEFT OUTER JOIN C C2 ON (B.BID = C2.BID AND B.BID = 'ZZZ');
"ADESC" "BDESC" "CDEST"
"adesc" "bdesc" "" -
Outer join two tables with query search record attached to both tables
When I create a query with two tables that have query search records attached with outer join, PS seems to do a natural join (cartesian). We are on PT8.48.
Is there a workaround for this issue. I do not want to remove query search record on either of the tables.
I am trying to create an Emergency contact report. I am using two tables PS_EMPLOYEES and PS_EMERGENCY_CNTCT. Here is the sql PeopleSoft query generated when I did Left outer Join.
Query SQL:
SELECT A.EMPLID, A.NAME, A.ADDRESS1, A.CITY, B.PRIMARY_CONTACT, B.ADDRESS1, B.CITY, B.STATE, B.POSTAL, B.RELATIONSHIP, A.DEPTID, A.JOBCODE, A.COMPANY, A.EMPL_TYPE
FROM (PS_EMPLOYEES A LEFT OUTER JOIN PS_EMERGENCY_CNTCT B ON A.EMPLID = B.EMPLID ), PS_EMPLMT_SRCH_QRY A1, PS_PERS_SRCH_QRY B1
WHERE A.EMPLID = A1.EMPLID
AND A.EMPL_RCD = A1.EMPL_RCD
AND A1.OPRID = 'SREESR'
AND (B.EMPLID = B1.EMPLID OR B.EMPLID IS NULL )
AND B1.OPRID = 'PS'
Appreciate any help.I think there are fixes for this issue in later tools releases (Report ID 1544345000). I'm not sure about 8.48, but you might try the workaround documented in
E-QR: Left Outer Joins with Security Records are returning unexpected results [ID 651252.1]
on Oracle Support.
Regards,
Bob -
I'm having problems registering jdbc drivers. I've been trying to register the microsoft Sql Server 2000 jdbc driver so that I can create a connection in my code rather than using entity beans. I've set the CLASSPATH variable to point to the driver's .jar files in the install directory with no success.
I've connected to the database using the driver via the IDE' s Runtime and it tests ok and allows me to create a database schema ok. (I had to copy the driver files to the sun/studio5u1_se/lib/ext dir to enable this) Is there a location I can unpack the drivers .jar files which will make the driver available?
I have also tried setting the CLASSPATH variable to point to the above mentioned directory..but that didn't work either. Can anyone help?
These are the exception messages that I get
java.lang.ClassNotFoundException: com.pointbase.jdbc.jdbcUniversalDriver
at java.net.URLClassLoader$1.run(URLClassLoader.java:199)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:187)
at java.lang.ClassLoader.loadClass(ClassLoader.java:289)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)
at java.lang.ClassLoader.loadClass(ClassLoader.java:235)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:141)
at Portfolio.DriverTest.getConnection(DriverTest.java:43)
at Portfolio.DriverTest.main(DriverTest.java:102)
Error Trace in getConnection() : com.pointbase.jdbc.jdbcUniversalDriverIf u type in command line
java -classpath .;<directory containing the driver>
it executes your class file properly
note that <directory containing the driver> is the full path to your driver. I mean, the directory that contains your driver\drivername
eg:
java -classpath .;c:/driver/drivername
don�t forget to put the "dot" before semicolon. If u forget it, java won�t find your class file. your class file must be at the directory you�re executing the command
I need to configure my sun studo ent. to locate my jdbc driver for mySQL. I don�t know where this can be made. If any of you know. please report me -
Connecting Oracle 7.3.4 with JDBC drivers 8.1.6
I am on a Solaris7 with Oracle 7.3.4 and drivers 8.1.6.
My code compiles and when it runs it gives me this error below:
ld.so.1: /usr/java1.1/bin/../bin/sparc/native_threads/java: fatal: libclntsh.so.
8.0: open failed: No such file or directory (/export/home/oracle7/app/oracle/pro
duct/7.3.4/lib/libocijdbc8.so)
java.lang.UnsatisfiedLinkError: no ocijdbc8 in shared library path
at java.lang.Throwable.<init>(Compiled Code)
at java.lang.Error.<init>(Compiled Code)
at java.lang.LinkageError.<init>(Compiled Code)
at java.lang.UnsatisfiedLinkError.<init>(Compiled Code)
at java.lang.Runtime.loadLibrary(Compiled Code)
at java.lang.System.loadLibrary(Compiled Code)
at oracle.jdbc.oci8.OCIDBAccess.logon(Compiled Code)
at oracle.jdbc.driver.OracleConnection.<init>(Compiled Code)
at oracle.jdbc.driver.OracleDriver.getConnectionInstance(Compiled Code)
at oracle.jdbc.driver.OracleDriver.connect(Compiled Code)
at java.sql.DriverManager.getConnection(Compiled Code)
at java.sql.DriverManager.getConnection(Compiled Code)
at jversion.main(Compiled Code)
I have all my paths in my LD_LIBRARY_PATH and the file it looks for is in the specified directory, and the permissions have been set correctly. I HAVE NO IDEA WHAT THE PROBLEM IS! Thank you in advance and ANY help would be appreciated,
isaac mosqueraYou shouldn't have to do anything "special" other than provide connectivity between the two databases.
Have you tried creating the database link yet? If so, did you receive errors? If not, then try it out and find out for yourself. -
Does the thin 1.2 JDBC driver support {oj outerjoin} syntax. I have no problem writing generic code for date or time using {d or {ts, but when I use {oj I get invalid SQL92 token?
Venturing a little over my head here...
Since the ODBC driver does support this syntax, and the JDBC driver can be set up to use the ODBC driver, it seems like this should be do-able.
The only problem would be to tell the JDBC driver not to parse the statement and to send it directly to the ODBC driver. I don't know whether this is possible, and if it is, how to do it.
Justin Cave
ODBC Development -
Datawindow graphical syntax outer join BUG
Ok, so this is a bug report. I don't know where i'm supposed to post it for SAP (i do have support).
The outer join syntax is ansi.
Using the graphical SQL designer, outer joins are incorrectly written by powerbuilder. This has been going on ever since ANSI style outer join sytax was added (PB 9?).
I think it has to do with the datawindow's use of both right and outer joins and its lack of use of inner joins. The end result is that we have to rewrite a lot of stuff in sql since powerbuilder is generating bad sql.
The typical example is the use of 2 or more outer joins where the joins are being done using 2 or more columns.
PB will create both a LEFT and a RIGHT outer join by duplicating the table name. The table (receive) is only selected ONCE in the sql graphical designer.
And this is the result:
Microsoft SQL Native Client
The objects "receive" and "receive" in the FROM clause have the same exposed names. Use correlation names to distinguish them.
Do you want to correct errors?
I would love to see the datawindow sql corrected and written in a more standard way.
1 change the OUTER JOIN syntax in the db profile setup to indicate the syntax. not outer join, but syntax. If you select ANSI have it write ALL joins using JOIN ( from ta join tb on ta.col = tb.col) intead of from tablea, tableb where tablea.col = tableb.col
2 - eliminate the use of right outer joins.
At that point i believe that the datawindow could more easily be fixed by SAP to not duplicate tables when in generates the syntax.If you have an Oracle Support agreement you can log a Service Request with Oracle, but they may respond that it is not really a bug. The problem is that the "outer" keyword in your 3rd example is being treated as an alias for TABLE_A because it is not considered a reserved keyword.
with table_a as (
select 1 as id, 'abc' as value_a from dual union all
select 2 as id, 'def' as value_a from dual union all
select 3 as id, 'ghi' as value_a from dual
, table_b as (
select 2 as id, 'jkl' as value_b from dual union all
select 3 as id, 'mno' as value_b from dual union all
select 4 as id, 'pqr' as value_b from dual
select ID, outer.VALUE_A, VALUE_B from TABLE_A outer join TABLE_B using (ID);
ID VALUE_A VALUE_B
2 def jkl
3 ghi mnoIf you query the V$RESERVED_WORDS view it will tell you which keywords are reserved.
select * from V$RESERVED_WORDS where keyword in ('OUTER', 'SELECT','USING');
KEYWORD LENGTH RESERVED RES_TYPE RES_ATTR RES_SEMI DUPLICATE
USING 5 N N N N N
OUTER 5 N N N N N
SELECT 6 Y N N N NYou would get a similar result if you tried
select ID, VALUE_A, VALUE_B from TABLE_A using join TABLE_B using (ID);Regards,
Bob -
Outer join with effective date in peoplesoft query
Hi,
I'm trying to join two tables using outer join. Both tables are effective dated:
Dept_Tbl: dept_id, status, effdt
Tips_Tbl: dept_id, tips_id, effdt
Not all records in Dept_Tbl are in Tips_Tbl. I need to get all active depts and their most recent tips_id if they have one.
select a.dept_id, b.tips_id
from dept_tbl a, tips_tbl b
where a.status = 'Active'
and a.effdt =
(select max(a_ed.effdt) from dept_tbl a_ed
where a.dept_id = a_ed.dept_id
and a_ed.effdt <= SYSDATE)
and b.dept_id(+) = a.dept_id
and b.effdt =
(select max(b_ed.effdt) from tips_tbl b_ed
where b.dept_id = b_ed.dept_id
and b.tips_id = b_ed.tips_id
and b_ed.effdt <= SYSDATE)
The query only returns records that are in both tables.
Is there a way for outer join to work with effective dates?
Thanks in advance,
RegHere is an example of one solution. Note the use of NVL on both sides of the equal sign since both sides could be NULL in the case of the outer join
with dept_tbl as (select 1 dept_id, SYSDATE effdt FROM DUAL),
tips_tbl as (select 1 dept_id, NULL effdt FROM DUAL)
select a.effdt
from dept_tbl a,
tips_tbl b
where b.dept_id(+) = a.dept_id
and NVL(b.effdt, SYSDATE) = NVL((select max(b_ed.effdt)
from tips_tbl b_ed
where b.dept_id = b_ed.dept_id
and b_ed.effdt <= SYSDATE), SYSDATE);
EFFDT
5/7/2007 3:25:00 PM -
SYNTAX "INNER JOIN and OUTER JOIN"
Hi Experts,
I think LEFT JOIN,INNER JOIN syntax is in ANSI.
I know that Oracle has got its own alternate(+) operator to serve the purpose.
Please tell me whether INNER JOIN,OUTER JOIN,LEFT JOIN,LEFT OUTER JOIN,RIGHT OUTER JOIN these syntaxes present in ORACLE 8I.
If not in 9i Or highr versions are they existing?
Thanks in advance,
Ananth
nullHi,
8i has inner join. (+) syntax supports LEFT or RIGHT OUTER JOIN.
FULL OUTER JOIN is supported in 9i, which introduces the JOIN keyword.
Herman -
OWB does not allow full outer join
I got following error (twice) while validating my mapping: "VLD-1506: Invalid Expression: Mixing full and partial outer joins in one mapping is not supported".
I have following join conditions in my mapping:
1) INGRP1.DISTRICT_ID = INGRP2.DISTRICT_ID And INGRP1.CHARGE_PERIOD_ID = INGRP2.CHARGE_PERIOD_ID And INGRP1.UTL_ID = INGRP2.UTL_ID
2) The same
3) INGRP1.CHARGE_PERIOD_ID (+) = INGRP2.CHARGE_PERIOD_ID (+) And
INGRP1.DISTRICT_ID (+) = INGRP2.DISTRICT_ID (+) And
INGRP1.PROVIDER# (+) = INGRP2.PROVIDER# (+)
I suppose there is not any partial joins here. I tried to make first and second conditions with full outer joins too:
INGRP1.DISTRICT_ID (+) = INGRP2.DISTRICT_ID (+) And
INGRP1.CHARGE_PERIOD_ID (+) = INGRP2.CHARGE_PERIOD_ID (+) And
INGRP1.UTL_ID (+) = INGRP2.UTL_ID (+) And
INGRP1.DISTRICT_ID IS NOT NULL And
INGRP2.DISTRICT_ID IS NOT NULL
If I do this, validation reports the same error, but six times instead of twice.
If I remove outer joins OWB generates following mapping statement:
MERGE
/*+ APPEND PARALLEL(MMB$ACCOUNT, DEFAULT, DEFAULT) */
INTO
"MMB$ACCOUNT"
USING
(SELECT
/*+ NO_MERGE */
"INGRP1"."DISTRICT_ID" "DISTRICT_ID",
DIC$TIME_RECODER."MONTH_ID" "MONTH_ID",
"INGRP1"."PROVIDER#" "PROVIDER#",
"INGRP1"."ACCOUNT_NO" "ACCOUNT_NO",
"INGRP2"."ACCOUNT_NO" "ACCOUNT_NO_1"
FROM "DIC$TIME_RECODER" DIC$TIME_RECODER,
(SELECT
/*+ DRIVING_SITE("AGG"."AGG_INPUT_SUBQUERY"."FC_CHARGES_1_GKH_REL2_GKH_STAR") */
"AGG"."CHARGE_PERIOD_ID" "CHARGE_PERIOD_ID",
"AGG"."DISTRICT_ID$0" "DISTRICT_ID",
"AGG"."PROVIDER#$0" "PROVIDER#",
"AGG"."ACCOUNT_NO$0" "ACCOUNT_NO"
FROM (SELECT
("AGG_INPUT_SUBQUERY"."CHARGE_PERIOD_ID$0") "CHARGE_PERIOD_ID",
("AGG_INPUT_SUBQUERY"."DISTRICT_ID$1") "DISTRICT_ID$0",
("AGG_INPUT_SUBQUERY"."PROVIDER#$1") "PROVIDER#$0",
COUNT(DISTINCT ("AGG_INPUT_SUBQUERY"."ACCOUNT_NO$1")) "ACCOUNT_NO$0"
FROM (SELECT
"INGRP1"."DISTRICT_ID" "DISTRICT_ID$1",
"INGRP1"."CHARGE_PERIOD_ID" "CHARGE_PERIOD_ID$0",
DM_UTILITIES_1_GKH_R14554."PROVIDER#" "PROVIDER#$1",
"FC_CHARGES_1_GKH_REL2_GKH_STAR"."ACCOUNT_NO" "ACCOUNT_NO$1"
FROM {"FC_CHARGES"@GKH_REL2_GKH_STAR} "FC_CHARGES_1_GKH_REL2_GKH_STAR",
{"DM_UTILITIES"@GKH_REL2_GKH_STAR} DM_UTILITIES_1_GKH_R14554,
(SELECT
"DEDUP"."DISTRICT_ID$2" "DISTRICT_ID",
"DEDUP"."CHARGE_PERIOD_ID$1" "CHARGE_PERIOD_ID",
"DEDUP"."UTL_ID" "UTL_ID"
FROM (SELECT
DISTINCT
"FC_CHARGES_GKH_REL2_GKH_STAR"."DISTRICT_ID" "DISTRICT_ID$2",
"FC_CHARGES_GKH_REL2_GKH_STAR"."CHARGE_PERIOD_ID" "CHARGE_PERIOD_ID$1",
"FC_CHARGES_GKH_REL2_GKH_STAR"."UTL_ID" "UTL_ID"
FROM {"FC_CHARGES"@GKH_REL2_GKH_STAR} "FC_CHARGES_GKH_REL2_GKH_STAR" WHERE ( (MAP_DIC$ACCOUNT."DATE_START") <= coalesce ( "FC_CHARGES_GKH_REL2_GKH_STAR"."CHANGED_DATE_#" , "FC_CHARGES_GKH_REL2_GKH_STAR"."CREATED_DATE_#" ) )) "DEDUP" ) "INGRP1" WHERE ( "INGRP1"."DISTRICT_ID" = "FC_CHARGES_1_GKH_REL2_GKH_STAR"."DISTRICT_ID" ) AND
( "INGRP1"."CHARGE_PERIOD_ID" = "FC_CHARGES_1_GKH_REL2_GKH_STAR"."CHARGE_PERIOD_ID" ) AND
( "INGRP1"."UTL_ID" = "FC_CHARGES_1_GKH_REL2_GKH_STAR"."UTL_ID" ) AND
( ( DM_UTILITIES_1_GKH_R14554."UTL_ID" (+) = "INGRP1"."UTL_ID" ) )) "AGG_INPUT_SUBQUERY"
GROUP BY
("AGG_INPUT_SUBQUERY"."DISTRICT_ID$1"), ("AGG_INPUT_SUBQUERY"."CHARGE_PERIOD_ID$0"), ("AGG_INPUT_SUBQUERY"."PROVIDER#$1")) "AGG" ) "INGRP1",
(SELECT
/*+ DRIVING_SITE("AGG_1"."AGG_INPUT_SUBQUERY$0"."FC_PAYMENTS_1_GKH_RE143940") */
"AGG_1"."PROVIDER#$2" "PROVIDER#",
"AGG_1"."DISTRICT_ID$3" "DISTRICT_ID",
"AGG_1"."CHARGE_PERIOD_ID$2" "CHARGE_PERIOD_ID",
"AGG_1"."ACCOUNT_NO$2" "ACCOUNT_NO"
FROM (SELECT
("AGG_INPUT_SUBQUERY$0"."PROVIDER#$3") "PROVIDER#$2",
("AGG_INPUT_SUBQUERY$0"."DISTRICT_ID$4") "DISTRICT_ID$3",
("AGG_INPUT_SUBQUERY$0"."CHARGE_PERIOD_ID$3") "CHARGE_PERIOD_ID$2",
COUNT(DISTINCT ("AGG_INPUT_SUBQUERY$0"."ACCOUNT_NO$3")) "ACCOUNT_NO$2"
FROM (SELECT
"INGRP1"."DISTRICT_ID" "DISTRICT_ID$4",
"INGRP1"."CHARGE_PERIOD_ID" "CHARGE_PERIOD_ID$3",
DM_UTILITIES_GKH_REL2_GKH."PROVIDER#" "PROVIDER#$3",
"FC_PAYMENTS_1_GKH_RE143940"."ACCOUNT_NO" "ACCOUNT_NO$3"
FROM {"FC_PAYMENTS"@GKH_REL2_GKH_STAR} "FC_PAYMENTS_1_GKH_RE143940",
{"DM_UTILITIES"@GKH_REL2_GKH_STAR} DM_UTILITIES_GKH_REL2_GKH,
(SELECT
"DEDUP_1"."DISTRICT_ID$5" "DISTRICT_ID",
"DEDUP_1"."CHARGE_PERIOD_ID$4" "CHARGE_PERIOD_ID",
"DEDUP_1"."UTL_ID$0" "UTL_ID"
FROM (SELECT
DISTINCT
"FC_PAYMENTS_GKH_REL2_GKH_STAR"."DISTRICT_ID" "DISTRICT_ID$5",
"FC_PAYMENTS_GKH_REL2_GKH_STAR"."CHARGE_PERIOD_ID" "CHARGE_PERIOD_ID$4",
"FC_PAYMENTS_GKH_REL2_GKH_STAR"."UTL_ID" "UTL_ID$0"
FROM {"FC_PAYMENTS"@GKH_REL2_GKH_STAR} "FC_PAYMENTS_GKH_REL2_GKH_STAR" WHERE ( (MAP_DIC$ACCOUNT."DATE_START") <= coalesce ( "FC_PAYMENTS_GKH_REL2_GKH_STAR"."CHANGED_DATE_#" , "FC_PAYMENTS_GKH_REL2_GKH_STAR"."CREATED_DATE_#" ) )) "DEDUP_1" ) "INGRP1" WHERE ( "INGRP1"."DISTRICT_ID" = "FC_PAYMENTS_1_GKH_RE143940"."DISTRICT_ID" ) AND
( "INGRP1"."CHARGE_PERIOD_ID" = "FC_PAYMENTS_1_GKH_RE143940"."CHARGE_PERIOD_ID" ) AND
( "INGRP1"."UTL_ID" = "FC_PAYMENTS_1_GKH_RE143940"."UTL_ID" ) AND
( ( DM_UTILITIES_GKH_REL2_GKH."UTL_ID" (+) = "INGRP1"."UTL_ID" ) )) "AGG_INPUT_SUBQUERY$0"
GROUP BY
("AGG_INPUT_SUBQUERY$0"."DISTRICT_ID$4"), ("AGG_INPUT_SUBQUERY$0"."CHARGE_PERIOD_ID$3"), ("AGG_INPUT_SUBQUERY$0"."PROVIDER#$3")) "AGG_1" ) "INGRP2" WHERE ( "INGRP1"."CHARGE_PERIOD_ID" = "INGRP2"."CHARGE_PERIOD_ID" ) AND
( "INGRP1"."DISTRICT_ID" = "INGRP2"."DISTRICT_ID" ) AND
( "INGRP1"."PROVIDER#" = "INGRP2"."PROVIDER#" ) AND
( ( DIC$TIME_RECODER."PERIOD_ID" (+) = "INGRP1"."CHARGE_PERIOD_ID" ) )
) "MERGEQUERY_325"
ON (
"MMB$ACCOUNT"."DISTRICT_ID" = "MERGEQUERY_325"."DISTRICT_ID" AND
"MMB$ACCOUNT"."MONTH_ID" = "MERGEQUERY_325"."MONTH_ID" AND
"MMB$ACCOUNT"."PROVIDER_ID" = "MERGEQUERY_325"."PROVIDER#" )
WHEN NOT MATCHED THEN
INSERT
("MMB$ACCOUNT"."DISTRICT_ID",
"MMB$ACCOUNT"."MONTH_ID",
"MMB$ACCOUNT"."PROVIDER_ID",
"MMB$ACCOUNT"."QNT_CHARGED",
"MMB$ACCOUNT"."QNT_PAID")
VALUES
("MERGEQUERY_325"."DISTRICT_ID",
"MERGEQUERY_325"."MONTH_ID",
"MERGEQUERY_325"."PROVIDER#",
"MERGEQUERY_325"."ACCOUNT_NO",
"MERGEQUERY_325"."ACCOUNT_NO_1")
WHEN MATCHED THEN
UPDATE
SET
"QNT_CHARGED" = "MERGEQUERY_325"."ACCOUNT_NO",
"QNT_PAID" = "MERGEQUERY_325"."ACCOUNT_NO_1";
What does it mean? Is JOINER's full outer join is incompatible with KEY LOOKUP operator and KL should be replaced with WB_LOOKUP_NUM?Sanders,
Key lookup always does a partial outer join. When the full outer join and partial outer join conditions are put together, there is no available syntax to facilitate it.
The way to this to generate the join operator (with full outer join) first in a subquery, then generate the key lookup as the outer query. Or the other way around, first the key lookup then the full outer join. The important part is that the key lookup can't be merged into the FROM-list.
So there are two workarounds. One is what you already pointed out, using WB_LOOKUP_NUM.
The other is to explicitly spell out the key lookup logic in the mapping by introducing a join with the lookup table, like this.
Change
Table1
.......... Join (w/ foj cond.) ---> KeyLookup
Table2
to
Table1
.......... Join (w/ foj cond)
Table2 ........................ Join (w/ poj cond.) ---> Lookup table
Nikolai Rochnik -
Outer join on OR operation alternate???
I have two tables stg and ads .I wanted to retreive all rows from stg table even if I dont find a match against ads
table on column cert but I need to check two matches against ads cert.One is with stg.cert and another with stg.cert1.
If outer join is possible with OR I would have used it. Can any one suggest a good solution other than using UNION? Thanks
Illegal :) syntax would be
Select t1.c1,t1.c2,t2.a1,t2.a2 from
stg t1,ads t2
where (t1.cert=t2.cert(+) or t1.cert1=t2.cert(+));
Thaks
HenaHi,
Oracle 8.1 was released in 1998. If you're using a 12-year-old version, that's pretty significant information, and it belongs in your first message.
Even if you're using a recent version of Oracle, it's helpful to say what that version is before people spend time giving you answers you can't use.
You might be able to do a UNION.
For example:
SELECT t1.c1, t1.c2, t2.a1, t2.a2
FROM stg t1
, ads t2
WHERE t2.cert IN (t1.cert, t1.cert1)
UNION ALL
SELECT t3.c1, t3.c2, NULL, NULL
FROM stg t3
WHERE NOT EXISTS (
SELECT 0
FROM ads t4
WHERE t4.cert IN (t3.cert, t3.cert1)
;Edited by: Frank Kulash on Oct 5, 2010 11:12 AM
Maybe you are looking for
-
External hard drive will not power on
I have a PH3200U-1E3S and it will not power up, every other push of the power button the light flashes once. I dont know what to do, any suggestions? The unit is not very old and it has all off our pictures on it. please help, Thanks Tony
-
Add Namespace in message mapping
Hi gurus, we have following requirement to solve; on receiver side we have a segment without namespace. It is possible to add namespace at the graphical mapping? <root> <id>1111</id> <name>max mustermann</name> <unit>B1</unit> </root> exp
-
I cannot install CS2 or 3 on my MacBook
Hello, I have an old PowerBook 1.25GHz that I had both cs2 and CS3 on, I just was given a barley used MacBook and proceeded to install CS2 first as I could not find he CS3 disk. It installed Photoshop and illustrator ok but did not install indesign.
-
I suddenly cannot connect to any wifi with my ipad 1. in settings my wifi is turned on. My home connection shows up under Choose a network and has a strong signal. I have reset the Wifi under General. But when I type in my password it still says, "Un
-
Backup failed with a non-descript error and 4.5 upgrade fails with fatal error
couldn't backup, somewhere in the middle of profiles the backup bombed each time, couldn't upgrade from 4.3. to 4.5 and browser application stopped working complaining about no service or something. it briefly worked after that, and than stopped aga