Oracle 11g - Nested loops on outer joins

Hello,
I have a select query that was working with no problems. The results are used to insert data into a temp table.
Recently, it would not complete executing. The explain plan shows a cartesian. But, there could be problems with using nested loops on the outer join. Interestingly, when I copy production code and rename the temp table and rename the view, it works.
Can someone take a look at the code and help. Maybe offer a suggestion on tuning too? Thanks.
CREATE TABLE "CT"
( "TN" VARCHAR2(30) NOT NULL ENABLE,
"COL_NAME" VARCHAR2(30) NOT NULL ENABLE,
"CDE" VARCHAR2(5) NOT NULL ENABLE,
"CDE_DESC" VARCHAR2(80) NOT NULL ENABLE,
"CDE_STAT" CHAR(1));
insert into CT (TN, COL_NAME, CDE, CDE_DESC, CDE_STAT)
values ('INDSD', 'STCD', 'U', 'RF', 'A');
insert into CT (TN, COL_NAME, CDE, CDE_DESC, CDE_STAT)
values ('AT', 'TCD', '001', 'RL', 'A');
insert into CT (TN, COL_NAME, CDE, CDE_DESC, CDE_STAT)
values ('AT', 'TCD', '033', 'PFR', 'A');
CREATE TABLE "IPP"
( "IND_ID" NUMBER(9,0) NOT NULL ENABLE,
"PLCD" VARCHAR2(5) NOT NULL ENABLE,
"CBCD" VARCHAR2(5));
insert into IPP (IND_ID, PLCD, CBCD)
values (2007, 'AS', '04');
insert into IPP (IND_ID, PLCD, CBCD)
values (797098, 'AS', '34');
insert into IPP (IND_ID, PLCD, CBCD)
values (797191, 'AS','04');
CREATE TABLE "INDS"
( "OPCD" VARCHAR2(5) NOT NULL ENABLE,
"IND_ID" NUMBER(9,0) NOT NULL ENABLE,
"IND_CID" NUMBER(*,0),
"GFLG" VARCHAR2(1),
"HHID" NUMBER(9,0),
"DOB" DATE,
"DOB_FLAG" VARCHAR2(1),
"VCD" VARCHAR2(5),
"VTDTE" DATE,
"VPPCD" VARCHAR2(4),
"VRCDTE" DATE NOT NULL ENABLE,
"VDSID" NUMBER(9,0),
"VTRANSID" NUMBER(12,0),
"VOWNCD" VARCHAR2(5),
"RCDTE" DATE,
"LRDTE" DATE
insert into INDS (OPCD, IND_ID, IND_CID, GFLG, HHID, DOB, DOB_FLAG, VCD, VTDTE, VPPCD, VRCDTE, VDSID, VTRANSID, VOWNCD, RCDTE, LRDTE)
values ('USST', 2007, 114522319, '', 304087673, to_date('01-01-1980', 'dd-mm-yyyy'), 'F', '2', to_date('06-04-2011 09:21:37', 'dd-mm-yyyy hh24:mi:ss'), '', to_date('06-04-2011 09:21:37', 'dd-mm-yyyy hh24:mi:ss'), 1500016, null, 'USST', to_date('06-04-2011 09:21:37', 'dd-mm-yyyy hh24:mi:ss'), to_date('18-07-2012 21:52:53', 'dd-mm-yyyy hh24:mi:ss'));
insert into INDS (OPCD, IND_ID, IND_CID, GFLG, HHID, DOB, DOB_FLAG, VCD, VTDTE, VPPCD, VRCDTE, VDSID, VTRANSID, VOWNCD, RCDTE, LRDTE)
values ('USST', 304087678, 115242519, '', 304087678, to_date('01-01-1984', 'dd-mm-yyyy'), 'F', '2', to_date('06-04-2011 09:21:39', 'dd-mm-yyyy hh24:mi:ss'), '', to_date('06-04-2011 09:21:39', 'dd-mm-yyyy hh24:mi:ss'), 1500016, null, 'USST', to_date('06-04-2011 09:21:39', 'dd-mm-yyyy hh24:mi:ss'), to_date('18-07-2012 21:52:53', 'dd-mm-yyyy hh24:mi:ss'));
CREATE TABLE "INDS_TYPE"
( "IND_ID" NUMBER(9,0) NOT NULL ENABLE,
"STCD" VARCHAR2(5) NOT NULL ENABLE);
insert into INDS_type (IND_ID, STCD)
values (2007, 'U');
insert into INDS_type (IND_ID, STCD)
values (313250322, 'U');
insert into INDS_type (IND_ID, STCD)
values (480058122, 'U');
CREATE TABLE "PLOP"
( "OPCD" VARCHAR2(5) NOT NULL ENABLE,
"PLCD" VARCHAR2(5) NOT NULL ENABLE,
"PPLF" VARCHAR2(1));
insert into PLOP (OPCD, PLCD, PPLF)
values ('USST', 'SP', 'Y');
insert into PLOP (OPCD, PLCD, PPLF)
values ('PMUSA', 'ST', '');
insert into PLOP (OPCD, PLCD, PPLF)
values ('USST', 'RC', '');
CREATE TABLE "IND_T"
( "OPCD" VARCHAR2(5) NOT NULL ENABLE,
"CID" NUMBER(9,0) NOT NULL ENABLE,
"CBCD" VARCHAR2(5),
"PF" VARCHAR2(1) NOT NULL ENABLE,
"DOB" DATE,
"VCD" VARCHAR2(5),
"VOCD" VARCHAR2(5),
"IND_CID" NUMBER,
"RCDTE" DATE NOT NULL ENABLE
insert into IND_T (OPCD, CID, CBCD,PF, DOB, VCD, VOCD, IND_CID, RCDTE)
values ('JMC', 2007, '04', 'F',to_date('11-10-1933', 'dd-mm-yyyy'), '2', 'PMUSA', 363004880, to_date('30-09-2009 04:31:34', 'dd-mm-yyyy hh24:mi:ss'));
insert into IND_T (OPCD, CID, CBCD,PF, DOB, VCD, VOCD, IND_CID, RCDTE)
values ('JMC', 2008, '04', 'N',to_date('01-01-1980', 'dd-mm-yyyy'), '2', 'PMUSA', 712606335, to_date('05-04-2013 19:36:05', 'dd-mm-yyyy hh24:mi:ss'));
CREATE TABLE "IC"
( "CID" NUMBER(9,0) NOT NULL ENABLE,
"CF" CHAR(1));
insert into IC (CID, CF)
values (2007, 'N');
insert into IC (CID, CF)
values (100, 'N');
insert into IC (CID, CF)
values (200, 'N');
CREATE OR REPLACE FORCE VIEW "INDSS_V" ("OPCD", "IND_ID", "IND_CID", "GFLG", "HHID", "DOB", "DOB_FLAG", "VCD", "VTDTE", "VPPCD", "VRCDTE", "VDSID", "VTRANSID", "VOWNCD", "RCDTE", "LRDTE") AS
SELECT DISTINCT a.OPCD, a.IND_ID, a.IND_CID, a.GFLG, a.HHID,
a.DOB, a.DOB_flag, a.VCD, a.VTDTE,
a.VPPCD, a.VRCDTE, a.VDSID, a.VTRANSID,
a.VOWNCD, a.RCDTE, a.LRDTE
FROM INDS a, INDS_type b
WHERE a.IND_ID = b.IND_ID
AND b.STCD in (select CDE
from CT --database link
where TN = 'INDSD'
and COL_NAME = 'STCD'
and CDE_STAT = 'A') ;
--insert /*+ parallel(IND_T,2) */ into IND_T
select /*+ parallel(a,4) */
a.OPCD as OPCD
, a.IND_ID as CID
, b.CBCD as CBCD
, NULL as BFCD
, 'N' as PF
, a.DOB as DOB
, a.VCD as VCD
, a.VOWNCD as VOCD
, a.IND_CID as IND_CID
, a.RCDTE as RCDTE
from INDSS_V a
, (select /*+ parallel(IPP,4) */ * from IPP IPP , PLOP PLO
where plo.PLCD = ipp.PLCD
and PPLF='Y') b
, IC c
where a.IND_ID = b.IND_ID (+)
and a.OPCD = b.OPCD (+)
and a.IND_ID = c.CID
and c.CF = 'N';

Please consult
HOW TO: Post a SQL statement tuning request - template posting
Also format your code and post it using the [ code ] and [ /code ] tags. (Leave out the extra space after [ and before ])
Sybrand Bakker
Senior Oracle DBA
Edited by: sybrand_b on 10-apr-2013 17:57

Similar Messages

  • Why optimizer prefers nested loop over hash join?

    What do I look for if I want to find out why the server prefers a nested loop over hash join?
    The server is 10.2.0.4.0.
    The query is:
    SELECT p.*
        FROM t1 p, t2 d
        WHERE d.emplid = p.id_psoft
          AND p.flag_processed = 'N'
          AND p.desc_pool = :b1
          AND NOT d.name LIKE '%DUPLICATE%'
          AND ROWNUM < 2tkprof output is:
    Production
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.01       0.00          0          0          4           0
    Execute      1      0.00       0.01          0          4          0           0
    Fetch        1    228.83     223.48          0    4264533          0           1
    total        3    228.84     223.50          0    4264537          4           1
    Misses in library cache during parse: 1
    Optimizer mode: ALL_ROWS
    Parsing user id: 108  (SANJEEV)
    Rows     Row Source Operation
          1  COUNT STOPKEY (cr=4264533 pr=0 pw=0 time=223484076 us)
          1   NESTED LOOPS  (cr=4264533 pr=0 pw=0 time=223484031 us)
      10401    TABLE ACCESS FULL T1 (cr=192 pr=0 pw=0 time=228969 us)
          1    TABLE ACCESS FULL T2 (cr=4264341 pr=0 pw=0 time=223182508 us)Development
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.01       0.00          0          0          0           0
    Execute      1      0.00       0.01          0          4          0           0
    Fetch        1      0.05       0.03          0        512          0           1
    total        3      0.06       0.06          0        516          0           1
    Misses in library cache during parse: 1
    Optimizer mode: ALL_ROWS
    Parsing user id: 113  (SANJEEV)
    Rows     Row Source Operation
          1  COUNT STOPKEY (cr=512 pr=0 pw=0 time=38876 us)
          1   HASH JOIN  (cr=512 pr=0 pw=0 time=38846 us)
         51    TABLE ACCESS FULL T2 (cr=492 pr=0 pw=0 time=30230 us)
        861    TABLE ACCESS FULL T1 (cr=20 pr=0 pw=0 time=2746 us)

    sanjeevchauhan wrote:
    What do I look for if I want to find out why the server prefers a nested loop over hash join?
    The server is 10.2.0.4.0.
    The query is:
    SELECT p.*
    FROM t1 p, t2 d
    WHERE d.emplid = p.id_psoft
    AND p.flag_processed = 'N'
    AND p.desc_pool = :b1
    AND NOT d.name LIKE '%DUPLICATE%'
    AND ROWNUM < 2
    You've got already some suggestions, but the most straightforward way is to run the unhinted statement in both environments and then force the join and access methods you would like to see using hints, in your case probably "USE_HASH(P D)" in your production environment and "FULL(P) FULL(D) USE_NL(P D)" in your development environment should be sufficient to see the costs and estimates returned by the optimizer when using the alternate access and join patterns.
    This give you a first indication why the optimizer thinks that the chosen access path seems to be cheaper than the obviously less efficient plan selected in production.
    As already mentioned by Hemant using bind variables complicates things a bit since EXPLAIN PLAN is not reliable due to bind variable peeking performed when executing the statement, but not when explaining.
    Since you're already on 10g you can get the actual execution plan used for all four variants using DBMS_XPLAN.DISPLAY_CURSOR which tells you more than the TKPROF output in the "Row Source Operation" section regarding the estimates and costs assigned.
    Of course the result of your whole exercise might be highly dependent on the actual bind variable value used.
    By the way, your statement is questionable in principle since you're querying for the first row of an indeterministic result set. It's not deterministic since you've defined no particular order so depending on the way Oracle executes the statement and the physical storage of your data this query might return different results on different runs.
    This is either an indication of a bad design (If the query is supposed to return exactly one row then you don't need the ROWNUM restriction) or an incorrect attempt of a Top 1 query which requires you to specify somehow an order, either by adding a ORDER BY to the statement and wrapping it into an inline view, or e.g. using some analytic functions that allow you specify a RANK by a defined ORDER.
    This is an example of how a deterministic Top N query could look like:
    SELECT
    FROM
    SELECT p.*
        FROM t1 p, t2 d
        WHERE d.emplid = p.id_psoft
          AND p.flag_processed = 'N'
          AND p.desc_pool = :b1
          AND NOT d.name LIKE '%DUPLICATE%'
    ORDER BY <order_criteria>
    WHERE ROWNUM <= 1;Regards,
    Randolf
    Oracle related stuff blog:
    http://oracle-randolf.blogspot.com/
    SQLTools++ for Oracle (Open source Oracle GUI for Windows):
    http://www.sqltools-plusplus.org:7676/
    http://sourceforge.net/projects/sqlt-pp/

  • Generally when does optimizer use nested loop and Hash joins  ?

    Version: 11.2.0.3, 10.2
    Lets say I have a table called ORDER and ORDER_DETAIL.
    ORDER_DETAIL is the child table of ORDERS .
    This is what I understand about Nested Loop:
    When we join ORDER AND ORDER_DETAIL tables oracle will form a 'nested loop' in which for each order_ID in ORDER table (outer loop), oracle will look for corresponding multiple ORDER_IDs in the ORDER_DETAIL table.
    Is nested loop used when the driving table (ORDER in this case) is smaller than the child table (ORDER_DETAIL) ?
    Is nested loop more likely to use Indexes in general ?
    How will these two tables be joined using Hash joins ?
    When is it ideal to use hash joins  ?

    Your description of a nested loop is correct.
    The overall rule is that Oracle will use the plan that it calculates to be, in general, fastest. That mostly means fewest I/O's, but there are various factors that adjust its calculation - e.g. it expects index blocks to be cached, multiple reads entries in an index may reference the same block, full scans get multiple blocks per I/O. It also has CPU cost calculations, but they generally only become significant with function / package calls or domain indexes (spatial, text, ...).
    Nested loop with an index will require one indexed read of the child table per outer table row, so its I/O cost is roughly twice the number of rows expected to match the where clause conditions on the outer table.
    A hash join reads the of the smaller table into a hash table then matches the rows from the larger table against the hash table, so its I/O cost is the cost of a full scan of each table (unless the smaller table is too big to fit in a single in-memory hash table). Hash joins generally don't use indexes - it doesn't use the index to look up each result. It can use an index as a data source, as a narrow version of the table or a way to identify the rows satisfying the other where clause conditions.
    If you are processing the whole of both tables, Oracle is likely to use a hash join, and be very fast and efficient about it.
    If your where clause restricts it to a just few rows from the parent table and a few corresponding rows from the child table, and you have an index Oracle is likely to use a nested loops solution.
    If the tables are very small, either plan is efficient - you may be surprised by its choice.
    Don't be worry about plans with full scans and hash joins - they are usually very fast and efficient. Often bad performance comes from having to do nested loop lookups for lots of rows.

  • Nested loop vs Hash Join

    Hi,
    Both the querys are returning same results, but in my first query hash join and second query nested loop . How ? PLs explain
    select *
    from emp a,dept b
    where a.deptno=b.deptno and b.deptno>20;
    6 rows
    Plan hash value: 4102772462
    | Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT             |         |     6 |   348 |     6  (17)| 00:00:01 |
    |*  1 |  HASH JOIN                   |         |     6 |   348 |     6  (17)| 00:00:01 |
    |   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |     3 |    60 |     2   (0)| 00:00:01 |
    |*  3 |    INDEX RANGE SCAN          | PK_DEPT |     3 |       |     1   (0)| 00:00:01 |
    |*  4 |   TABLE ACCESS FULL          | EMP     |     7 |   266 |     3   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - access("A"."DEPTNO"="B"."DEPTNO")
       3 - access("B"."DEPTNO">20)
       4 - filter("A"."DEPTNO">20)
    select *
    from emp a,dept b
    where a.deptno=b.deptno and b.deptno=30;  
    6 rows
    Plan hash value: 568005898
    | Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT             |         |     5 |   290 |     4   (0)| 00:00:01 |
    |   1 |  NESTED LOOPS                |         |     5 |   290 |     4   (0)| 00:00:01 |
    |   2 |   TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    20 |     1   (0)| 00:00:01 |
    |*  3 |    INDEX UNIQUE SCAN         | PK_DEPT |     1 |       |     0   (0)| 00:00:01 |
    |*  4 |   TABLE ACCESS FULL          | EMP     |     5 |   190 |     3   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       3 - access("B"."DEPTNO"=30)
       4 - filter("A"."DEPTNO"=30)

    Hi,
    Unless specifically requested, Oracle picks the best execution plan based on estimates of table sizes, column selectivity and many other variables. Even though Oracle does its best to have the estimates as accurate as possible, they are frequently different, and in some cases quite different, from the actual values.
    In the first query, Oracle estimated that the predicate “ b.deptno>20” would limit the number of records to 6, and based on that it decided the use Hash Join.
    In the second query, Oracle estimated that the predicate “b.deptno=30” would limit the number of records to 5, and based on that it decided the use Nested Loops Join.
    The fact that the actual number of records is the same is irrelevant because Oracle used the estimate, rather the actual number of records to pick the best plan.
    HTH,
    Iordan
    Iotzov

  • Translating SQL from MYSQL to ORACLE with more than one outer join.

    I will translate the following sqlquery from MYSQL to ORACLE:
    SELECT ticket.ticket_no,ticket.ticket_dato,ticket.ticket_subject,ticket.customer_id,customer_name,ticket.ticket_own_read, ticket.department_id, department.department_name, priority_name, tickstat_name, tickettype_name
    FROM customer, ticket left join department
    on ticket.department_id = department.department_id left join priority on ticket.priority_id = priority.priority_id
    left join ticketstatus on ticket.tickstat_id = ticketstatus.tickstat_id
    left join tickettype on ticket.tickettype_id = tickettype.tickettype_id
    where ticket.customer_id = customer.customer_id and customer.owner_id =
    #session.owner_id#
    I have tried in ORACLE with:
    SELECT ticket.ticket_no,ticket.ticket_dato,ticket.ticket_subject,ticket.customer_id,customer_name,ticket.ticket_own_read, ticket.department_id, department.department_name, priority_name, tickstat_name, tickettype_name
    FROM customer, ticket ,department, priority, ticketstatus, tickettype
    where
    ticket.department_id(+) = department.department_id and
    ticket.priority_id(+) = priority.priority_id and
    ticket.tickstat_id(+) = ticketstatus.tickstat_id and
    ticket.tickettype_id(+) = tickettype.tickettype_id and
    ticket.customer_id = customer.customer_id and customer.owner_id = #session.owner_id#
    I get an error:
    MERANT][ODBC Oracle driver][Oracle]ORA-01417: a table may be outer joined to at most one other table
    How do I translate the code to ORACLE?

    I think that your syntax is wrong. The (+) operator should be on the right hand table column, not the left hand table column if you want all rows on the left hand table column. If this syntax is really what you want, you can create underlying views for each join condiction.

  • ORACLE 11g + PHP5 problem: "fetch out of sequence" on remote database link

    Hi!
    I have a new server with oracle 11g (11.1.0.7) database and apache/php5 (actual build) on linux.
    connection type is dedicated.
    when doing a connection to a remote AS/400 database I always get this error:
    "Warning: oci_fetch_array() http://function.oci-fetch-array: ORA-01002: fetch out of sequence ORA-02063: preceding line from..."
    when doing the same simple "select * from database link" at my old server with oracle 9i and apache/php5 no problem occurrs.
    this happens at AS/400 database link only. normal oracle database links work fine.
    Anyone an idea how to solve this problem or where the problem is????
    further info:
    when doing " select * from [ database link ] where rownum < 11 " it works, but when doing the query with more than 10 results I get the error. Any idea?
    bye,
    Oliver
    Edited by: user501548 on 10.10.2008 02:20

    well a fetch out of sequence usually indicates that a cursor has been closed before the process has finished fetching or some such thing.
    I'm not aware of there being a specific problem with the situation you outline, but maybe if you could provide all the connection setup and how you are trying to connect that may give a better idea.
    Also, you may be better asking on the General Database Discussions forum as this isn't really a SQL or PL/SQL problem

  • ORACLE 11g + PHP5 problem: "fetch out of sequence" on i5/OS AS/400

    Hi!
    I have a big problem using a database connection to i5 AS/400 with PHP5 OCI8 interface by Oracle 11g:
    when doing a simple "select * from (as400_database_link)" I get this return: "fetch out of sequence... preceding line..."
    I never had this problem with 9i, old transparent gateway.
    BUT:
    when doing for example a "select * from (as400_database_link) where rownum < 1000000" it works fine without problems.
    Anyone an idea how to eliminate this stupid "where rownum < 100000" behaviour?
    I would have to add this in many select statements... ;(
    bye,
    Oliver

    Tach,
    how do you call oci_execute ?
    try oci_execute($query,OCI_DEFAULT);
    I had the same problem with adodb
    $q = " select * from elephant@africa";
    $db->GetAll($q);
    Failed with the same error.
    ADODB called oci_execute with OCI_COMMIT_ON_SUCCESS,which caused my error.
    $q = " select * from elephant@africa";
    $db->BeginTrans();
    $db->GetAll($q);
    $db->CommitTrans(); (or rollback);
    did the job,because BeginTrans changed oci_execute to run with OCI_DEFAULT.
    Hope this helps,
    gw
    Edited by: unficyp123 on Oct 20, 2008 2:51 PM

  • Hash join vs nested loop

    DECLARE @tableA table (Productid varchar(20),Product varchar(20),RateID int)
    insert into @tableA values('1','Mobile',2);
    insert into @tableA values('2','Chargers',4);
    insert into @tableA values('3','Stand',6);
    insert into @tableA values('4','Adapter',8);
    insert into @tableA values('5','Cover',10);
    insert into @tableA values('6','Protector',12);
    --SELECT * FROM @tableA
    DECLARE @tableB table (id varchar(20),RateID int,Rate int)
    insert into @tableB values('1',2,200);
    insert into @tableB values('2',4,40);
    insert into @tableB values('3',6,60);
    insert into @tableB values('4',8,80);
    insert into @tableB values('5',10,10);
    insert into @tableB values('6',12,15);
    --SELECT * FROM @tableB
    SELECT Product,Rate
    FROM @tableA a
    JOIN @tableB b ON a.RateID = b.RateID
    Above is the sample query, where in execution plan it shows the Hash Match (inner Join). Now how do I change it to Nested Loop with out changing the query? help plz

    Is Hash Match(inner join) or Nested loop is better to have in the query?
    That depends on the size of the tables, available indexes etc. The optimizer will (hopefully) make the best choice.
    Above is the sample query, where in execution plan it shows the Hash Match (inner Join). Now how do I change it to Nested Loop with out changing the query?
    The answer that you should leave that to the optimizer in most cases.
    I see that the logical read for nested loop is higher than Hash Match.
    But Hash Match tends to need more CPU. The best way to two compare two queries or plans is wallclock time.
    On a big tables, how do we reduce the logical read? 
    Make sure that there are usable indexes.
    Erland Sommarskog, SQL Server MVP, [email protected]

  • 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';

  • Multiple LEFT OUTER JOIN on Oracle 8i

    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 c.display(+)=b.display
    and c.name(+)='Done';
    Thanks.

    Rewrite as:
    select a.id, b.id
    from test, test1 b
    WHERE a.id(+)=b.id
    and a.display(+)=b.display
    and a.name(+)='Done';
    Though I would lose the (+) in a.name(+) = 'Done' unless you want every name.

  • OUTER JOIN 의 GUIDE LINE

    제품 : ORACLE SERVER
    작성날짜 : 2002-04-10
    OUTER JOIN 에 대하여
    ====================
    Purpose
    Outer join의 효과과 이용방법에 대해 이해한다.
    Explanation
    1. 개념
    다음의 용어에 대해 우선 살펴보자 :
    1) outer-join column - symbol(+) 을 사용하는 column 이다 .
    예를 들어 EMPNO(+) ,DEPT.DEPTNO(+) 는 outer join column들이다.
    2) simple predicate - AND , OR,NOT 을 가지지 않는 단순한 관계표현으로
    A=B 의 관계로 표현된다.
    3) outer join predicate - 한개 이상의 outer join column 을 갖는 simple
    predicate 이다.
    2. OUTER JOIN 사용법 - RULES
    outer join predicate 는 오직 1 table 의 column 들 만이 outer join
    column 으로 이용되어져야 한다. 즉 한 single outer join predicate 의
    모든 outer join column 은 모두 같은 table이어야 한다.
    이런 취지에서 다음 statement 는 틀린 것이다.
    EMP.EMPNO(+) = DEPT.DEPTNO(+)
    이것은 두 table 의 outer join column 들이다.
    한 predicate 의 한 column 이 outer join column 이면 같은 table 의 모든
    column 은 outer join column 이어야 한다.
    이 취지에서 다음 문장은 틀린 것이다.
    EMP.SAL + EMP.COMM(+) = SALGRADE.HIGH
    한 table 의 column 들이 outer join 것과 아닌 것과 outer join 인것으로
    섞여있기 때문이다.
    predicate 에서 (+) 표시가 붙은 table 은 다른 table 을 direct 하게
    outer join 한다. indirect 하게 다른 tabe 을 outer join 한다는 것은
    그들 table 자체가 또 outer join 하는 경우이다.
    이 경우 한 table 은 direct하게든 indeirect 하게든 자기 자신에게 outer
    join 하는 경우는 허용되지 않는다.
    다음의 문장은 이런 취지에서 틀린 경우이다.
    EMP.EMPNO(+) = PERS.EMPNO
    AND PERS.DEPTNO(+) = DEPT.DEPTNO
    AND DEPT.JOB(+) = EMP.JOB - circular outer
    join relationship
    3. OUTER JOIN 실행
    주어진 table T 에는 outer join 과 non-outer join 이 있다.
    실행시 다음처럼 수행된다.
    1) The result of joining all tables mentioned in table T's
    outer join predicates is formed ( by recursive application
    of this algorithm ).
    2) For each row of the result, a set of composite rows is
    formed, each consisting of the original row in the
    result joined to a row in table T for which the composite
    row satisfies all of table T's outer join predicates.
    3) If a set of composite rows is the null set, a composite
    row is created consisting of the original row in the
    result joined to a row similar to those in table T, but
    with all values set to null.
    4) Rows that do not pass the non-outer join predicates are removed.
    This may be summarised as follows. Outer join
    predicates ( those with (+) after a column of table T ), are
    evaluated BEFORE table T is augmented with a null row. The null
    row is added only if there are NO rows in table T that satisfy
    the outer join predicates. Non-outer join predicates are
    evaluated AFTER table T is augmented with a null row (if needed)
    4. OUTER JOIN - RECOMMENDATIONS
    Certain types of outer joins in complicated logical
    expressions may not be well formed. In general, outer join
    columns in predicates that are branches of an OR should be
    avoided. Inconsistancies between the branches of the OR can
    result in an ambiguous query, and this may not be detected. It
    is best to confine outer join columns to the top level of the
    'where' clause, or to nested AND's only.
    5. OUTER JOIN - ILLUSTRATIVE EXAMPLES
    1) Simple Outer Join
    SELECT ENAME, LOC
    FROM DEPT, EMP
    WHERE DEPT.DEPTNO = EMP.DEPTNO(+)
    The predicate is evaluated BEFORE null augmentation. If
    there is a DEPT row for which there are no EMP rows, then a null
    EMP row is concatenated to the DEPT row.
    2) Outer Join With Simple Post-Join Predicates
    SELECT ENAME, LOC
    FROM DEPT, EMP
    WHERE DEPT.DEPTNO = EMP.DEPTNO(+)
    AND EMP.DEPTNO IS NULL
    The second simple predicate is avaluated AFTER null
    augmentation, since there is no (+), removing rows which were
    not the result of null augmentation and hence leaving only DEPT
    rows for which there was no corresponding EMP row.
    3) Outer Join With Additional Pre-Join Predicates
    SELECT ENAME, LOC
    FROM DEPT, EMP
    WHERE DEPT.DEPTNO = EMP.DEPTNO(+)
    AND 'CLERK' = EMP.JOB(+)
    AND EMP.DEPTNO IS NULL
    The predicate on EMP.JOB is evaluated at the same time
    as the one on EMP.DEPTNO - before null augmentation. As a
    result, a null row is augmented to any DEPT row for which there
    are no corresponding clerks's in the EMP table. Therefore, this
    query displays departments containing no clerks.
    Note that it the (+) were omitted from the EMP.JOB
    predicate, no rows would be returned. In this case, both the
    EMP.JOB and EMP.DEPTNO IS NULL predicates are evaluated AFETR
    the outer join, and there can be no rows for which both are
    true.

    I had to put it in a subquery? (if that's what it's called)
    SELECT a1.date_field DateAndHour, b1.OR_date, NVL(b1.record_count,0)
    FROM  MASTER_DATE_TABLE a1,
                  (SELECT TO_CHAR(b.OR_IN_DTTM,'YYYYMMDDHH24') OR_date, COUNT(*) record_count
                FROM hsa_tgt.PICIS_OR b
                GROUP BY TO_CHAR(b.OR_IN_DTTM,'YYYYMMDDHH24')) b1
    WHERE a1.date_field  = b1.OR_date (+)
    GROUP BY a1.date_field, b1.OR_date, b1.record_count
    HAVING (TO_DATE(a1.date_field,'YYYYMMDDHH24') BETWEEN '01-Jan-2006' AND '31-Jan-2006')
    ORDER BY a1.date_field;

  • OUTER JOIN -- Error: ORA-01417  (a table may be outer joined to at most one

    Hi there,
    I have a rather simple task: retrieve all the records in a table, for agiven domain p_domain_id (input parameter). The problem is that there are about 6 FKs in the table, and I need the names (strings) corresponding to those FKs (from other tables). Unfortunately, some of the FKs are NULL, so in '=' I loose records. Without the last 2 lines in WHERE clause, I get the correct result. With d2 in place (and without the "(+)" ) I loose 2 records. With the d3 (and also without "(+)"), I do not get any record.
    With the "(+)", the code compiles but I get the run time error ORA-01417
    NOTE: I put the "+" within parentheses, in order to show it like a text in this editor.
    What's an elegant solution to this?
    Thanks a lot.
    Here's the code:
    SELECT
    a.DOMAIN,
    b.NAME,
    a.DE_ID,
    a.NAME,
    a.PREFERRED_LABEL,
    a.TECHNICAL_DEFINITION,
    a.PUBLIC_DEFINITION,
    a.DE_TYPE,
    c1.NAME,
    a.HAS_PARAMETER,
    a.VALUE_CLASS,
    c2.NAME,
    a.INDEX_TERMS,
    a.DATA_TABLE_ID,
    d1.TABLE_NAME,
    a.SP_INSERT,
    a.SP_UPDATE,
    a.SP_GET_BYMRN,
    a.SP_GET_BYATTRIBUTE,
    a.VALUE_TABLE_ID,
    d2.TABLE_NAME,
    a.PARAM_TABLE_ID,
    d3.TABLE_NAME,
    a.PARAM_DOMAIN_LOGIC,
    a.SP_LOV,
    a.LOWER_LIMIT,
    a.UPPER_LIMIT,
    a.BOOLEAN_Y,
    a.BOOLEAN_N,
    a.COMMENTS,
    a.ENTERED_BY,
    commons_API.get_person_full_name(a.ENTERED_BY),
    a.ENTERED_ON
    FROM
    DATA_ELEMENT_INDEX a,
    DE_DOMAIN b,
    GENERAL_LIST c1,
    GENERAL_LIST c2,
    TABLE_GROUP d1,
    TABLE_GROUP d2,
    TABLE_GROUP d3
    WHERE
    DOMAIN = p_domain_id AND
    b.DOMAIN_ID = a.DOMAIN AND
    c1.ID = a.DE_TYPE AND
    c2.ID = a.VALUE_CLASS AND
    d1.TABLE_ID = a.DATA_TABLE_ID AND -- it works well without the next two lines
    d2.TABLE_ID = a.VALUE_TABLE_ID "(+)" AND
    d3.TABLE_ID = a.PARAM_TABLE_ID "(+)"
    ORDER BY a.NAME;
    Edited by: user10817976 on Oct 19, 2009 8:14 AM

    One of my standard replies...
    Oracle syntax does not support outer joining to more than one table.
    However ANSI syntax does...
    SQL> select * from a;
            ID      B_KEY      C_KEY
             1          2          3
             2          1          4
             3          3          1
             4          4          2
    SQL> select * from b;
            ID     C_KEY2
             1          1
             2          5
             3          3
             4          2
    SQL> select * from c;
          KEY1       KEY2 DTA
             1          1 1-1
             1          2 1-2
             1          3 1-3
             1          4 1-4
             2          1 2-1
             2          2 2-2
             2          3 2-3
             2          4 2-4
             3          1 3-1
             3          2 3-2
             3          3 3-3
             3          4 3-4
             4          1 4-1
             4          2 4-2
             4          3 4-3
             4          4 4-4
    16 rows selected.
    SQL> ed
    Wrote file afiedt.buf
      1  select a.id as a_id, b.id as b_id, c.key1 as c_key1, c.key2 as c_key3, c.dta
      2  from a, b, c
      3  where a.b_key = b.id
      4  and   a.c_key = c.key1 (+)
      5* and   b.c_key2 = c.key2 (+)
    SQL> /
    and   a.c_key = c.key1 (+)
    ERROR at line 4:
    ORA-01417: a table may be outer joined to at most one other table
    SQL> ed
    Wrote file afiedt.buf
      1  select a.id as a_id, b.id as b_id, c.key1 as c_key1, c.key2 as c_key3, c.dta
      2  from a JOIN b ON (a.b_key = b.id)
      3*        LEFT OUTER JOIN c ON (a.c_key = c.key1 and b.c_key2 = c.key2)
    SQL> /
          A_ID       B_ID     C_KEY1     C_KEY3 DTA
             3          3          1          3 1-3
             4          4          2          2 2-2
             2          1          4          1 4-1
             1          2
    SQL>

  • 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,
    Ed

    I 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

  • For got my Oracle 11g R2 Password

    Hi.
    I unfortunately forgot Oracle 11g R2 Password. For my goodness it doesn't contain any Important data.As a newbie to Oracle I would like to know how to retrieve the data for Oracle 11g Data Base with out knowing the password.
    Is is possible to get into data base or is there any way to retrieve my password through Response files present during Installation?

    Tejaswi.B wrote:
    Hi.
    I unfortunately forgot Oracle 11g R2 Password. For my goodness it doesn't contain any Important data.As a newbie to Oracle I would like to know how to retrieve the data for Oracle 11g Data Base with out knowing the password.
    Is is possible to get into data base or is there any way to retrieve my password through Response files present during Installation?If you loss password then you can not get this,but you can change this password.Connect with other user or as sysdba
    sqlplus "/as sysdba"
    alter user user_name identified by pass

  • Inner Selects vs. Outer Joins

    We have a report where we are joining many tables (25 tables) together. Initially, we created the report with outer joins and noticed that the cost of the explain plan was 2600 and the performance was adequate. We then started to remove the outer joins and replacing with inner selects and the cost and performance of the report improved. Currently, we have replaced 13 of the outer joins with inner selects and the cost is down to 650.
    Typically, I have always used joins or outer joins because I thought this was best practice. However, I am now questioning this.
    Is it better to use inner selects when you are only returning one column from a table?
    Other than tables that require multiple columns to be returned, are there issues we should be concerned with?
    Below are examples:
    Thanks,
    Brian
    -- Using Outer Joins
    Select q.quote_id, q.quote_name, l.location_name, sr.sales_rep_name
    from quote q, location l, sales_rep sr
    where q.location_id = l.loation_id (+)
    and q.sales_rep_id = sr.sales_rep_id (+)
    -- Using Inner Selects
    Select q.quote_id, q.quote_name,
    (select location_name from location where location_id = q.location_id) location_name,
    (select sales_rep_name from sales_rep where sales_rep_id = q.sales_rep_id) sales_rep_name
    from quote q

    The cost of a query does not mean better performance. The scalar subqueries that you use when rewriting that query show up in your explain plan with no cost at all, and this is just no true. (a query must "cost" something, right?)
    Instead of starting to rewrite your queries using scalara subqueries, it's better to investigate why a query performs bad.
    If using scalar subquery would always yield a better performance, Oracle would probably rewrite all outer join queries to using scalar subquery.

Maybe you are looking for

  • My 5th gen Nano won't Sync

    So, I have plugged my iPod in. On the actual iPod the screen says it connects and syncs, but none of my songs have gone onto it. Itunes knows its plugged in, but pressing sync doesn't do anything.

  • How can I change owner name in my IPad?

    I won an IPad as a prize at a trade show. The owner name is set as the company that I gave it to me.  How can I change the owner name to me?  I cannot find anything in the 'settings' for this.

  • Problem with camera on z1

    i have a problem with the camera it doesn't launch from the shutter key directly the camera either gives me a "camera not available" error when i unlock the phone or i have to unlock the phone to launch the camera what to do??????

  • Using the Process.getOutputStream() method

    Hi all, i have written a java program that executes System commands and returns output... this program works fine if you want to only execute the command and returns output... but suppose that the program that you executed waits for you to input some

  • LANDSCAPE or PORTRAIT ?

    Dears, After book was submitted, I got following msg from Apple: "All vital content (images, text, etc) now needs to be available in both landscape and portrait mode. Currently, all content is missing in portrait mode. Surely some of you already expe