Outer join that give no result

Hi everybody
Here are the scripts
CREATE TABLE dem_comment (
COMMENTID VARCHAR2(50 BYTE) NOT NULL,
PARENTID VARCHAR2(50 BYTE) NOT NULL,
DEM_DATE_CREATION_MEMO date)
CREATE TABLE demand(
NUM_PCE VARCHAR2(14 BYTE) NOT NULL,
NUM_DEMANDE VARCHAR2(8 BYTE)
insert into dem_comment VALUES (1,'12345ABCDEF',to_date('17/08/2012 10:18:34','DD/mm/YYyy HH:MI:SS'))
insert into demand values('12345','ABCDEF')
And the following is the request that have the problem
select dem.NUM_PCE, memo.parentid
from demand dem, dem_comment memo
where CONCAT(dem.NUM_PCE,dem.NUM_DEMANDE) = memo.parentId (+)
and memo.DEM_DATE_CREATION_MEMO = (select MAX(DEM_DATE_CREATION_MEMO)
FROM dem_comment memo
WHERE memo.parentId = CONCAT(dem.NUM_PCE,dem.NUM_DEMANDE))
And the result is the one i m waiting for
NUMPCE | PARENTID
12345 | 12345ABCDEF
but when i delete the record from dem_comment, (because of the outer join) i m supposed to have something like
NUMPCE | PARENTID
12345 |
but the result is that, no record
NUMPCE | PARENTID
The outer join seems to not work
Thank you for your help

UW (Germany) wrote:
Sorry, I was too fast and did not notice the nested select. Try this:
select dem.NUM_PCE, memo.parentid
from demand dem
left outer join dem_comment memo on CONCAT(dem.NUM_PCE,dem.NUM_DEMANDE) = memo.parentId
where memo.DEM_DATE_CREATION_MEMO is null
or memo.DEM_DATE_CREATION_MEMO = (select MAX(DEM_DATE_CREATION_MEMO)
FROM dem_comment memo
WHERE memo.parentId = CONCAT(dem.NUM_PCE,dem.NUM_DEMANDE));
It is an left outer join, so the predicate on the left table belongs in the on clause
from demand dem
left outer join dem_comment memo
on CONCAT(dem.NUM_PCE,dem.NUM_DEMANDE) = memo.parentId
and
memo.DEM_DATE_CREATION_MEMO = (select MAX(DEM_DATE_CREATION_MEMO)
                                        FROM dem_comment memo
                                      WHERE memo.parentId = CONCAT(dem.NUM_PCE,dem.NUM_DEMANDE))

Similar Messages

  • Old outer join syntax produces different results from new syntax!

    I have inherited a query that uses the old outer join syntax but that is yielding correct results. When I translate it to the new outer join syntax, I get the results I expect, but they are not correct! And I don't understand why the old syntax produces the results it produces. Bottom line: I want the results I'm getting from the old syntax, but I need it in the new syntax (I'm putting it into Reporting Services, and RS automatically converts old syntax to new).
    Here's the query with the old outer join syntax that is working correctly:
    Code Snippet
    SELECT   TE = COUNT(DISTINCT T1.ID),
             UE = COUNT(DISTINCT T2.ID),
             PE = CONVERT(MONEY, COUNT(DISTINCT T2.ID)) / 
                  CONVERT(MONEY,COUNT(DISTINCT T1.ID))
    FROM     TABLE T1, TABLE T2
    WHERE    T1 *= T2
    In this query, much to my surprise, TE <> UE and PE <> 1. However, TE, UE, and PE seem to be accurate!
    Here's the query with the new outer join syntax that is working but not producing the results I need:
    Code Snippet
    SELECT   TE = COUNT(DISTINCT T1.ID),
             UE = COUNT(DISTINCT T2.ID),
             PE = CONVERT(MONEY, COUNT(DISTINCT T2.ID)) / 
                  CONVERT(MONEY,COUNT(DISTINCT T1.ID))
    FROM     TABLE T1 LEFT OUTER JOIN TABLE T2 ON T1.ID = T2.ID
    Though not producing the results I need, it is producing what would be expected: TE = UE and PE = 1.
    My questions:
    1) Can someone who is familiar enough with the old syntax please help me understand why TE <> UE and PE <> 1 in the first query?
    2) Can someone please tell me how to properly translate the first query to the new syntax so that it continues to produce the results in the first query?
    Thank you very much.

    How can we reproduce the issue?
    Code Snippet
    USE [master]
    GO
    EXEC sp_dbcmptlevel Northwind, 80
    GO
    USE [Northwind]
    GO
    SELECT
    TE
    = COUNT(DISTINCT T1.OrderID),
    UE = COUNT(DISTINCT T2.OrderID),
    PE = CONVERT(MONEY, COUNT(DISTINCT T2.OrderID)) /
    CONVERT(MONEY,COUNT(DISTINCT T1.OrderID))
    FROM
    dbo
    .Orders T1, dbo.Orders T2
    WHERE
    T1
    .OrderID *= T2.OrderID
    SELECT
    TE
    = COUNT(DISTINCT T1.OrderID),
    UE = COUNT(DISTINCT T2.OrderID),
    PE = CONVERT(MONEY, COUNT(DISTINCT T2.OrderID)) /
    CONVERT(MONEY,COUNT(DISTINCT T1.OrderID))
    FROM
    dbo
    .Orders T1
    LEFT OUTER JOIN
    dbo.Orders T2
    ON T1.OrderID = T2.OrderID
    GO
    EXEC sp_dbcmptlevel Northwind, 90
    GO
    Result:
    TE
    UE
    PE
    830
    830
    1.00
    TE
    UE
    PE
    830
    830
    1.00
    As you can see, I am getting same results.
    AMB

  • How to use outer join to display the results

    I want to develop a report in which the column sequence will be as follows:
    1)Item_code
    2)Item_name
    3)Stock
    4)Pending
    5)Re-order Level
    6)Item_reorder_qty
    I had written the query, but the problem is all the products does not get displayed. The products are more than 700. But after running the query, only 364 gets displayed.
    How i can make use of outer join in the following statements :
    AND ITEM_CODE = LCS_ITEM_CODE
    AND ITEM_CODE = PI_ITEM_CODE
    AND LCS_ITEM_CODE = PI_ITEM_CODE
    in the below given query to solve this.
    SELECT
    ITEM_CODE,
    ITEM_NAME,
    ((LCS_STK_QTY_BU + LCS_RCVD_QTY_BU - LCS_ISSD_QTY_BU- LCS_REJECT_QTY_BU)/IU_MAX_LOOSE_1)STK ,
    SUM(TO_NUMBER(PI_QTY||'.'||PI_QTY_LS) - (PI_GI_QTY_BU/IU_CONV_FACTOR/IU_MAX_LOOSE_1))PNDG,
    ITEM_RORD_LVL,
    ITEM_RORD_QTY
    FROM
    OM_ITEM,
    OM_ITEM_UOM,
    OT_PO_HEAD,
    OT_PO_ITEM,
    OS_LOCN_CURR_STK
    WHERE (ITEM_UOM_CODE = IU_UOM_CODE AND ITEM_CODE = IU_ITEM_CODE)
    AND ITEM_CODE = LCS_ITEM_CODE
    AND ITEM_CODE = PI_ITEM_CODE
    AND LCS_ITEM_CODE = PI_ITEM_CODE
    AND LCS_LOCN_CODE ='RM'
    AND PI_PH_SYS_ID = PH_SYS_ID
    GROUP BY ITEM_CODE,ITEM_NAME,LCS_STK_QTY_BU,LCS_RCVD_QTY_BU,LCS_ISSD_QTY_BU,LCS_REJECT_QTY_BU,IU_MAX_LOOSE_1,ITEM_RORD_LVL,ITEM_RORD_QTY
    ORDER BY ITEM_CODE ASC
    Yogesh

    As you have no table aliases I can't tell what columns relate to which tables on your join conditions.
    Can you not just put (+) next to the outer joined columns you require on the where clause? Or perhaps consider using ANSI syntax for the joins such as <tableA> LEFT OUTER JOIN <tableB> ON (<join conditions>)

  • Outer Join Puzzle; Refactor Affects Results, Unexpectedly

    Good afternoon. I have a complex query which is returning some unexpected results. Oddly, moving a specific join outside of the original query changes the results returned in a field from another table. This is a simplified version:
    SELECT
    A.PK,
    A.Field1,
    B.Field2,
    C.Field3
    FROM
    A
    INNER JOIN B ON A.PK = B.PK
    LEFT JOIN  C ON A.PK = C.PK
    WHERE
    A.Field = 'X'...running this query, I get 29 records but only one non-null value in C.Field3. If I then rewrite the query like this:
    SELECT A.PK, A.Field1, B.Field2, A.Field3
    FROM
    SELECT
      A.PK,
      A.Field1,
      C.Field3
    FROM
      A
      LEFT JOIN C ON A.PK = C.PK
    WHERE
      A.Field = 'X'
    ) A
    INNER JOIN B ON A.PK = B.PKSuddenly I get lots of values in Field3. I don't understand how this reorganization could affect the values returned. What am I missing?
    The joins are all one-to-one, or to be exact one-to-zero-or-one.
    Thank you,
    Jonathan

    Hi, Jonathan,
    I don't see any obvious mistakes.
    I suspect that when you simplified the question, you inadvertently removed the part that was causing the problem.
    Post a little sample data (CREATE TABLE and INSERT statements for all tables, relevant columns only) that produces the strange results.
    I suggest not using aliases that are the same as the names of tables in the same query. For example, since a is a table name, also using a as an alias for the in-line view that joins a and c is just inviting confusion. It's probably not causing your present problem, but why not call the sub-query by some unique name, like ac?

  • Same join query gives difeerent results on changing alias

    I executed the following query,
    select      distinct(gr1.i_supergroups_names)
    from      dm_group_r gr1,
         dm_group_r gr2
    where      gr1.r_object_id = gr2.r_object_id and
         gr2.users_names = 'grass_mig3'
    322 rows returned.
    Immediately, I executed the same query again with a minor change in the join condition. Instead of GR2.USER_NAMES, i used GR1.USER_NAMES.
    i.e.
    select      distinct(gr1.i_supergroups_names)
    from      dm_group_r gr1,
         dm_group_r gr2
    where      gr1.r_object_id = gr2.r_object_id and
         gr1.users_names = 'grass_mig3'
    284 rows returned.
    Would anyone be able to help me as to why the query is functioning like this?
    This is the first time I am facing this problem Until now, I had never even thought that using different aliases could change the end result. Whenever I wrote a query, I would blindly use any one of the aliases?

    I'm just wondering if your queries are equivalent
    select distinct(gr1.i_supergroups_names)
    from dm_group_r gr1,
    dm_group_r gr2
    where gr1.r_object_id = gr2.r_object_id and
    gr2.users_names = 'grass_mig3'
    select distinct(gr1.i_supergroups_names)
    from dm_group_r gr1,
    dm_group_r gr2
    where gr1.r_object_id = gr2.r_object_id and
    gr1.users_names = 'grass_mig3' Well, I think they are.
    Henry's question is valid why don't you just rewrite your query to
    select distinct(gr1.i_supergroups_names)
    from dm_group_r gr1
    where gr1.users_names = 'grass_mig3'
    and   gr1.r_object_id is not null -- NULLs here got eliminated by the join aboveMessage was edited by:
    Jens Petersen

  • Outer Join not giving correct result

    I have two tables=> tab_child_tmp (product_id,region,child_val,mst_product) and
    tab_master_tmp (master_product_id,region,master_val)
    tab_child_tmp.mst_product is the foreign key referencing tab_master_tmp.master_product_id.
    Currently the tables are populated with below values
    tab_child_tmp
    PRODUCT_ID REGION CHILD_VAL MST_PRODUCT
    Arm-01,     CAL,     100,     Arm-Master
    Arm-01,     DEL,     222,     Arm-Master
    Arm-01,     CHEN,     55,     Arm-Master
    Arm-02,     MUM,     69,     Arm-Master
    Arm-02,     DEL,     90,     Arm-Master
    tab_master_tmp
    MST_PRODUCT     REGION     MASTER_VAL
    Arm-Master     , CAL,     390
    Arm-Master     , DEL,     300
    Arm-Master, CHEN,     450
    Arm-Master, MUM,     600
    Now I want to display the result in the below format
    PRODUCT_ID REGION CHILD_VAL MASTER_VAL
    1. Arm-01     , CAL, 100,     390
    2. Arm-01     , DEL, 222,     300
    3. Arm-01     , CHEN, 55,     450
    4. Arm-01     , MUM, 0,     600
    5. Arm-02     , MUM, 69,     600
    6. Arm-02     , DEL, 90,     300
    7. Arm-02     , CHEN, 0,     450
    8. Arm-02     , CAL, 0,     390
    When I am running the below query it is not returning the above 4,7 and 8 rows. Can you please provide the correct sql to get the above desired output
    SELECT
    a.product_id,
    nvl(a.region,b.region) geo,
    nvl(a.child_val,0)match_val,
    b.master_val
    FROM
    tab_child_tmp a,
    tab_master_tmp b
    WHERE
    a.mst_product(+) = b.master_product AND
    a.region(+) = b.region
    Thanks

    Hi
    Thanks for the reply. Please find below the details.
    Oracle Version*
    Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
    PL/SQL Release 10.2.0.1.0 - Production
    CORE     10.2.0.1.0     Production
    TNS for Solaris: Version 10.2.0.1.0 - Production
    NLSRTL Version 10.2.0.1.0 - Production
    Create Table Script_
    create table TAB_CHILD_TMP
    PRODUCT_ID VARCHAR2(50),
    REGION VARCHAR2(100),
    CHILD_VAL NUMBER,
    MST_PRODUCT VARCHAR2(50)
    create table TAB_MASTER_TMP
    MST_PRODUCT VARCHAR2(50),
    REGION VARCHAR2(100),
    MASTER_VAL NUMBER
    Insert Script_
    INSERT INTO tab_child_tmp VALUES ('Arm-01','CAL',100,'Arm-Master');
    INSERT INTO tab_child_tmp VALUES ('Arm-01','DEL',222,'Arm-Master');
    INSERT INTO tab_child_tmp VALUES ('Arm-01','CHEN',55,'Arm-Master');
    INSERT INTO tab_child_tmp VALUES ('Arm-Master','MUM',69,'PLC1');
    INSERT INTO tab_child_tmp VALUES ('Arm-Master','DEL',90,'PLC1');
    INSERT INTO tab_master_tmp VALUES ('Arm-Master','CAL',390);
    INSERT INTO tab_master_tmp VALUES ('Arm-Master','DEL',300);
    INSERT INTO tab_master_tmp VALUES ('Arm-Master','CHEN',450);
    INSERT INTO tab_master_tmp VALUES ('Arm-Master','MUM',600);
    INSERT INTO tab_master_tmp VALUES ('PLC1','MUM',199);
    INSERT INTO tab_master_tmp VALUES ('PLC1','DEL',299);
    INSERT INTO tab_master_tmp VALUES ('PLC1','CHEN',399);
    Expected output logic*
    Need to display the product value for each region along with the value of master product for the corresponding product and region. If a product doesn't belong to a particular region, but the corresponding master product is, then that value also needs to be displayed for that product and region with child value as zero.
    ie. for product Arm-01 there is no record in tab_child_tmp for region "MUM", but it's master product 'Arm-Master' has a record for region 'MUM' in tab master_tmp table. So in ouput there will be a record for product 'Arm-01' and region-'MUM' with child value as 0 and master value as 600.
    Expected Output*
    PRODUCT_ID ~~~ REG ~~~ CHILD_VAL ~~~ MASTER_VAL
    Arm-01 ~~~ CAL ~~~ 100 ~~~ 390
    Arm-01 ~~~ DEL ~~~ 222 ~~~ 300
    Arm-01 ~~~ CHEN ~~~ 55 ~~~ 450
    Arm-01 ~~~ MUM ~~~ 0 ~~~ 600
    Arm-MASTER ~~~ MUM ~~~ 69 ~~~ 199
    Arm-MASTER ~~~ DEL ~~~ 90 ~~~ 299
    Arm-MASTER ~~~ CHEN ~~~ 0 ~~~ 399
    Please help

  • Confused on RIGHT OUTER JOIN

    Here is a query and desired output for a weekly sales report. The problem is that if no data exists for given businessdate, the report is empty. It should show store with zeroed totals.
    NOTES:
    1. storenbr must be string
    2. bow, eow = beginning and end of week
    3. I have no say-so on the date format
    with report_stores  as
    (  select  501   as storeid from dual union all
        select   22   as storeid from dual union all
        select   24   as storeid from dual
    , store_details as
        select   501   as storeid,   '6504'    as storenbr,  'Quincey Circle' as storename  from dual union all
        select   22   as storeid,    '2385'    as storenbr,  'Goodlet' as storename   from dual union all
        select   24   as storeid,    '4290'   as storenbr,  'Poplar' as storename   from dual
    , sales_data as
        select  501 as storeid,  to_date('12/01/2010', 'MM/DD/YYYY')    as businessdate,  100 as sales_amt, 50 as guestcount from dual union all
        select  22  as storeid,  to_date('12/01/2010', 'MM/DD/YYYY')    as businessdate,  200 as sales_amt, 50 as guestcount from dual union all
        select  24  as storeid,  to_date('12/01/2010', 'MM/DD/YYYY')   as businessdate,  300 as sales_amt, 50 as guestcount from dual  union all
        select  501 as storeid,  to_date('12/02/2010', 'MM/DD/YYYY')   as businessdate,  400 as sales_amt, 100 as guestcount from dual union all
        select  22  as storeid,  to_date('12/02/2010', 'MM/DD/YYYY')    as businessdate,  500 as sales_amt, 100 as guestcount from dual union all
        select  24  as storeid,  to_date('12/02/2010', 'MM/DD/YYYY')    as businessdate,  600 as sales_amt, 100 as guestcount from dual 
    select  storenbr
    ,       to_date('01/30/2011', 'MM/DD/YYYY') as EOW
    ,       sum(nvl(sales_amt, 0))              as sales_amount
    ,       sum(nvl(sales.guestcount , 0))      as guestcount
    from report_stores   stores
    inner join store_details details on details.storeid = stores.storeid
    left outer join sales_data sales    on  sales.storeid = stores.storeid 
                                      and   sales.businessdate  between  to_date('01/24/2011',  'MM/DD/YYYY') and to_date('01/30/2011', 'MM/DD/YYYY')
    group by storename,      to_date('01/30/2011', 'MM/DD/YYYY');However, when I make date dynamic by adding a dates table, I don't get output.
    with report_dates as
       select to_date('01/05/2011', 'MM/DD/YYYY') as businessdate, 'Wednesday' as day_name, 2 as week_nbr,   to_date('01/03/2011', 'MM/DD/YYYY')  as bow,   to_date('01/09/2011', 'MM/DD/YYYY')  as eow from dual union all
       select to_date('01/24/2011', 'MM/DD/YYYY') as businessdate, 'Monday'    as day_name, 5 as week_nbr,   to_date('01/24/2011', 'MM/DD/YYYY')  as bow,   to_date('01/30/2011', 'MM/DD/YYYY')  as eow from dual
    , report_stores  as
    (  select  501   as storeid from dual union all
        select   22   as storeid from dual union all
        select   24   as storeid from dual
    , store_details as
        select   501   as storeid,   '6504'    as storenbr,  'Quincey Circle' as storename  from dual union all
        select   22   as storeid,    '2385'    as storenbr,  'Goodlet' as storename   from dual union all
        select   24   as storeid,    '4290'   as storenbr,  'Poplar' as storename   from dual
    , sales_data as
        select  501 as storeid,  to_date('12/01/2010', 'MM/DD/YYYY')    as businessdate,  100 as sales_amt, 50 as guestcount from dual union all
        select  22  as storeid,  to_date('12/01/2010', 'MM/DD/YYYY')    as businessdate,  200 as sales_amt, 50 as guestcount from dual union all
        select  24  as storeid,  to_date('12/01/2010', 'MM/DD/YYYY')   as businessdate,  300 as sales_amt, 50 as guestcount from dual  union all
        select  501 as storeid,  to_date('12/02/2010', 'MM/DD/YYYY')   as businessdate,  400 as sales_amt, 100 as guestcount from dual union all
        select  22  as storeid,  to_date('12/02/2010', 'MM/DD/YYYY')    as businessdate,  500 as sales_amt, 100 as guestcount from dual union all
        select  24  as storeid,  to_date('12/02/2010', 'MM/DD/YYYY')    as businessdate,  600 as sales_amt, 100 as guestcount from dual 
    select storenbr
    ,       eow
    ,       sum(nvl(sales_amt, 0))                as sales_amount
    ,       sum(nvl(sales.guestcount , 0))      as guestcount
    from report_stores              stores
    inner join store_details        details   on details.storeid = stores.storeid
    right outer join sales_data     sales     on  sales.storeid = stores.storeid 
    inner join report_dates         dte       on    dte.businessdate =   to_date('01/24/2010', 'MM/DD/YYYY')
                                        --    and   sales.businessdate between   bow  and   eow
    group by storenbr, eow
    ;What am I doing wrong? For kicks I also tried switching the JOINS like :
    Select *
    from sales_data sales
    left outer join report_stores            stores on stores.stoeid = sales.storeid but couldn't make this work either.

    Hi,
    Thanks for posting the sample data in a useful form.
    Don't forget to post the results you want to get from that data. Is this what you want?
    STOR EOW         SALES_AMOUNT GUESTCOUNT
    6504                        0          0
    2385                        0          0
    4290                        0          0If so, you want to inner-join sales_data and report_dates, and then outer-join that result set to report_stores.
    Here's one way to do that:
    SELECT    details.storenbr
    ,         dte.eow
    ,         NVL (SUM (sales.sales_amt),  0)       AS sales_amount
    ,         NVL (SUM (sales.guestcount), 0)       AS guestcount
    FROM           report_stores   stores
    INNER JOIN      store_details      details          ON     details.storeid        = stores.storeid
    LEFT OUTER JOIN (     sales_data      sales
                      JOIN     report_dates    dte         ON      sales.businessdate  BETWEEN   dte.bow 
                                                           AND           dte.eow
              )                      ON       sales.storeid          = stores.storeid
    GROUP BY  details.storenbr
    ,             dte.eow
    ;As in your first query, you want the every row in report_stores to appear in the output, whether it matches anything in sales+dte or not, so you want to continue saying "FROM report_stores ... *LEFT* OUTER JOIN ...".
    You'll notice that I changed
    SUM (NVL (x, 0)) to
    NVL (SUM (x), 0). Both give the same results, but, if you have 1000 rows, the former calls NVL 1000 times, but the latter only calls NVL once, so it's more efficient.

  • OUTER JOINS

    I am a user of Dicoverer 4.1 and I write queries from the EUL. I need help in writing my query that will return all records in Table A and matching and Null values from Table B. A simple employee roster with all Names(Table A)and all addresses(Table B)including Null addresses. Here is the exact sql statement I get from a simple query that only gives me employees who have addresses (I know there are some who don't have addresses).
    SELECT POSITION_EMPLOYEE_SECV.NAME_PERS, ADDRESS_SECV.LOCAL_ADDR_CITY
    FROM CSUDB.POSITION_EMPLOYEE_SECV POSITION_EMPLOYEE_SECV, CSUDB.ADDRESS_SECV ADDRESS_SECV
    WHERE ( ( POSITION_EMPLOYEE_SECV.SSAN_EMPL_CON_NR = ADDRESS_SECV.SSAN_EMPL_CON_NR ) );
    How do I write the outer join that will give me all employees and include the ones with no address?
    Thanks.

    Change the where clause to-
    WHERE ((POSITION_EMPLOYEE_SECV.SSAN_EMPL_CON_NR = ADDRESS_SECV.SSAN_EMPL_CON_NR(+)));
    Good luck!

  • Outer join vs. 'SELECT in SELECT'

    Hi All,
    I am generally curious about which method to use between a Outer join and 'SELECT in SELECT'. We can have same result with both methods.
    My question is, for real life complex queries, which method is more efficiant? less resource intensive? Any thories you guys have?
    I am on Oracle 10.2 on lunix.
    See my example below
    -- First table
    create table emp
    id   number,
    name varchar2(1000),
    constraint emp_pk primary key ( id )
    -- second table. There will be 1 record, for few of the records in EMP table, in this table
    create table leave
    id     number,
    emp_id number,
    leave_date date,
    constraint leave_pk primary key (id),
    constraint leave_fk foreign key ( emp_id ) references emp
    create index leave_idx_1 on leave ( emp_id ) ;
    -- Populate some sample data in there
    insert into emp (id, name)
    select object_id, object_name from dba_objects where rownum < 10001 ;
    declare
    cursor c1 is
       select id from emp where mod(id,2) = 0 ;
    v_id  number := 1 ;
    v_date DATE := '01-JAN-08';
    begin
      for c2 in c1
      loop
          insert into leave values ( v_id, c2.id, v_date );
          v_id := v_id + 1;
          v_date := v_date + 1;
      end loop;
    end;
    -- Set autotrace
    set autotrace traceonly explain
    -- =================================
    -- Outer join
    -- =================================
    select e.id, e.name, l.id, l.leave_date
    from   emp e, leave l
    where  e.id = l.emp_id (+) ;
    -- ===================================
    -- select in select to get same results as above outer join
    -- ===================================
    select e.id, e.name,
           (select l.id from leave l where l.emp_id = e.id ) leave_id,
           (select l.leave_date from leave l where l.emp_id = e.id ) leave_date
    from   emp e ;My hidden question, how these two methods internally work? in the plan we can only see something like 'hash join right outer' or something like that. But how exactly outer join is executed? how is the result formed?
    I have got following plans for the two methods
    SQL> select e.id, e.name, l.id, l.leave_date
      2  from   emp e, leave l
      3  where  e.id = l.emp_id (+) ;
    Elapsed: 00:00:00.03
    Execution Plan
    Plan hash value: 98076489
    | Id  | Operation             | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT      |       | 10000 |  5371K|    16   (7)| 00:00:01 |
    |*  1 |  HASH JOIN RIGHT OUTER|       | 10000 |  5371K|    16   (7)| 00:00:01 |
    |   2 |   TABLE ACCESS FULL   | LEAVE |  5012 |   171K|     6   (0)| 00:00:01 |
    |   3 |   TABLE ACCESS FULL   | EMP   | 10000 |  5029K|     9   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - access("E"."ID"="L"."EMP_ID"(+))
    Note
       - dynamic sampling used for this statement
    SQL> select e.id, e.name,
      2         (select l.id from leave l where l.emp_id = e.id ) leave_id,
      3         (select l.leave_date from leave l where l.emp_id = e.id ) leave_date
      4  from   emp e ;
    Elapsed: 00:00:00.18
    Execution Plan
    Plan hash value: 2670217481
    | Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT            |             | 10000 |  5029K|     9   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| LEAVE       |    50 |  1300 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | LEAVE_IDX_1 |    20 |       |     1   (0)| 00:00:01 |
    |   3 |  TABLE ACCESS BY INDEX ROWID| LEAVE       |    50 |  1100 |     2   (0)| 00:00:01 |
    |*  4 |   INDEX RANGE SCAN          | LEAVE_IDX_1 |    20 |       |     1   (0)| 00:00:01 |
    |   5 |  TABLE ACCESS FULL          | EMP         | 10000 |  5029K|     9   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       2 - access("L"."EMP_ID"=:B1)
       4 - access("L"."EMP_ID"=:B1)
    Note
       - dynamic sampling used for this statementPlease let me know your thoughts.
    Thanks in advance

    A better indicator of performance would be to look at the number of consistent gets that are required to execute the query.
    In my environment:
    SQL> SELECT * FROM V$VERSION;
    BANNER
    Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
    PL/SQL Release 10.2.0.4.0 - Production
    CORE    10.2.0.4.0      Production
    TNS for 64-bit Windows: Version 10.2.0.4.0 - Production
    NLSRTL Version 10.2.0.4.0 - Production
    SQL> SHOW PARAMETER OPT
    NAME                                 TYPE        VALUE
    filesystemio_options                 string
    object_cache_optimal_size            integer     102400
    optimizer_dynamic_sampling           integer     2
    optimizer_features_enable            string      10.2.0.4
    optimizer_index_caching              integer     0
    optimizer_index_cost_adj             integer     100
    optimizer_mode                       string      ALL_ROWS
    optimizer_secure_view_merging        boolean     TRUE
    plsql_optimize_level                 integer     2The OUTER JOIN produced the following results:
    SQL> select e.id, e.name, l.id, l.leave_date
      2  from   emp e, leave l
      3  where  e.id = l.emp_id (+) ;
    10000 rows selected.
    Execution Plan
    Plan hash value: 98076489
    | Id  | Operation             | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT      |       | 10000 |   380K|     9  (12)| 00:00:01 |
    |*  1 |  HASH JOIN RIGHT OUTER|       | 10000 |   380K|     9  (12)| 00:00:01 |
    |   2 |   TABLE ACCESS FULL   | LEAVE |  5017 | 80272 |     3   (0)| 00:00:01 |
    |   3 |   TABLE ACCESS FULL   | EMP   | 10000 |   224K|     5   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - access("E"."ID"="L"."EMP_ID"(+))
    Statistics
              0  recursive calls
              0  db block gets
            723  consistent gets
              0  physical reads
              0  redo size
         364047  bytes sent via SQL*Net to client
           7672  bytes received via SQL*Net from client
            668  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
          10000  rows processedThe inline subquery produced these results:
    SQL> select e.id, e.name,
      2         (select l.id from leave l where l.emp_id = e.id ) leave_id,
      3         (select l.leave_date from leave l where l.emp_id = e.id ) leave_dat
      4  from   emp e ;
    10000 rows selected.
    Execution Plan
    Plan hash value: 1706216391
    | Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT  |       | 10000 |   224K|     5   (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| LEAVE |     1 |     9 |     3   (0)| 00:00:01 |
    |*  2 |  TABLE ACCESS FULL| LEAVE |     1 |    13 |     3   (0)| 00:00:01 |
    |   3 |  TABLE ACCESS FULL| EMP   | 10000 |   224K|     5   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter("L"."EMP_ID"=:B1)
       2 - filter("L"."EMP_ID"=:B1)
    Statistics
              0  recursive calls
              0  db block gets
         360705  consistent gets
              0  physical reads
              0  redo size
         364053  bytes sent via SQL*Net to client
           7672  bytes received via SQL*Net from client
            668  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
          10000  rows processedSee the 723 consistent gets versus 360705? That is a huge difference.
    The second method may be more viable if you create indexes on the columns in the leave table that you are joining to your EMP table.
    For example:
    SQL> CREATE INDEX LEAD_ID_IDX ON LEAVE(EMP_ID, ID, LEAVE_DATE);
    Index created.
    SQL> set autotrace traceonly
    SQL> select e.id, e.name,
      2         (select l.id from leave l where l.emp_id = e.id ) leave_id,
      3         (select l.leave_date from leave l where l.emp_id = e.id ) leave_date
      4  from   emp e ;
    10000 rows selected.
    Execution Plan
    Plan hash value: 1822800249
    | Id  | Operation         | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT  |             | 10000 |   224K|     5   (0)| 00:00:01 |
    |*  1 |  INDEX RANGE SCAN | LEAD_ID_IDX |     1 |     9 |     2   (0)| 00:00:01 |
    |*  2 |  INDEX RANGE SCAN | LEAD_ID_IDX |     1 |    13 |     2   (0)| 00:00:01 |
    |   3 |  TABLE ACCESS FULL| EMP         | 10000 |   224K|     5   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - access("L"."EMP_ID"=:B1)
       2 - access("L"."EMP_ID"=:B1)
    Statistics
              1  recursive calls
              0  db block gets
          22111  consistent gets
             19  physical reads
              0  redo size
         364053  bytes sent via SQL*Net to client
           7672  bytes received via SQL*Net from client
            668  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
          10000  rows processedThe query improved by a more than a factor of 10 with the index but the consistent gets are still significantly higher then the OUTER JOIN query. Additionally I always try and take the approach when developing queries to minimize the number of table accesses possible. In your second place you have to access the LEAVE table twice, instead of once in the first query.

  • Choice of left or right outer join

    Hi Experts,
    I have a two tables like named as emp demo
    desc emp
    empname varchar2(50)
    empid number
    desc demo
    empname varchar2(50)
    empid number
    when i implement the below quries i'm getting the same o/p.
    queries like
    select e.ename from emp e left outer join demo d on (e.empid=d.empid);
    select e.ename from demo d right outer join emp e on (d.empid=e.empid);
    In this case which query is most prefer
    Thnks in advance
    H

    Hi,
    943338 wrote:
    Hi Experts,
    I have a two tables like named as emp demo
    desc emp
    empname varchar2(50)
    empid number
    desc demo
    empname varchar2(50)
    empid number
    when i implement the below quries i'm getting the same o/p.Right. You're getting the same error, because there is no ename column. If you change ename to empname, then you'll still get the same results, because
    x LEFT OUTER JOIN y    ON zis equivalent to
    y RIGHT OUTER JOIN x    ON zin results and performance.
    queries like
    select e.ename from emp e left outer join demo d on (e.empid=d.empid);
    select e.ename from demo d right outer join emp e on (d.empid=e.empid);
    In this case which query is most preferBoth are equally efficient.
    Since most people never use RIGHT OUTER JOIN, it might make maintenance eaiser if you don't use it, either. I would use LEFT OUTER JOIN.

  • One-to-many outer join in MView, is possible?

    Re: 10g R2
    Is it simply not possible to have fast refresh on outer joins that are 1-to-many relations? I have in this script a unique key addition to "fix" it, but it restricts something that I don't want restricted. If indeed this is how it should work, are there any strategies for improving performance for queries on this type of thing? The "fact_table" in this example is actually another materialized view with simple inner joins, so that works perfectly, but I was trying to improve query performance in this case too.
    Run the script w/ dbms output...all self contained within the schema.
    drop materialized view log on fact_Table;
    drop materialized view log on outer_detail;
    drop materialized view mview_test;
    drop table outer_detail cascade constraints;
    drop table fact_Table cascade constraints;
    create table fact_table (myid number primary key, fact_attrib varchar2(10));
    create table outer_detail (myid number primary key, outer_attrib varchar2(19), fact_table_id number, constraint fk_outer_to_Fact foreign key (fact_table_id) references fact_table(myid));
    CREATE MATERIALIZED VIEW LOG ON fact_table WITH ROWID;
    CREATE MATERIALIZED VIEW LOG ON outer_detail WITH ROWID;
    declare
        v_capabilities sys.ExplainMVArrayType ;
    begin
        dbms_mview.explain_mview('SELECT ft.rowid "ftrid", ' ||
           'od.rowid "odrid", ' ||
           'ft.myid fact_id, ' ||
           'od.myid outer_id, ' ||
           'ft.fact_attrib, ' ||
           'od.outer_attrib ' ||
      'FROM fact_table ft, outer_detail od ' ||
    'WHERE ft.myid = od.fact_table_id (+)', v_capabilities);
            dbms_output.put_line('ATTEMPT 1:');
            dbms_output.put_line('==============================================');
        for v_capability in (select capability_name, possible, related_text, msgtxt from table (v_capabilities))
        loop
            dbms_output.put_line('==============================================');
            dbms_output.put_line('==============================================');
            dbms_output.put_line(v_capability.capability_name);
            dbms_output.put_line(v_capability.possible);
            dbms_output.put_line(v_capability.related_text);
            dbms_output.put_line(v_capability.msgtxt);
        end loop;
    end;
    /*CREATE MATERIALIZED VIEW mview_test
    PARALLEL BUILD IMMEDIATE
    REFRESH FAST ON COMMIT WITH ROWID
    AS
    SELECT ft.rowid "ftrid",
           od.rowid "odrid",
           ft.myid fact_id,
           od.myid outer_id,
           ft.fact_attrib,
           od.outer_attrib
      FROM fact_table ft, outer_detail od
    WHERE ft.myid = od.fact_table_id (+);
    -- I'd like it to run without this constraint, is it not possible?
    alter table outer_detail add constraint unk_outer_detail unique (fact_table_id);
    declare
        v_capabilities sys.ExplainMVArrayType ;
    begin
        dbms_mview.explain_mview('SELECT ft.rowid "ftrid", ' ||
           'od.rowid "odrid", ' ||
           'ft.myid fact_id, ' ||
           'od.myid outer_id, ' ||
           'ft.fact_attrib, ' ||
           'od.outer_attrib ' ||
      'FROM fact_table ft, outer_detail od ' ||
    'WHERE ft.myid = od.fact_table_id (+)', v_capabilities);
            dbms_output.put_line('');
            dbms_output.put_line('');
            dbms_output.put_line('');
            dbms_output.put_line('ATTEMPT 2:');
            dbms_output.put_line('==============================================');
        for v_capability in (select capability_name, possible, related_text, msgtxt from table (v_capabilities))
        loop
            dbms_output.put_line('==============================================');
            dbms_output.put_line('==============================================');
            dbms_output.put_line(v_capability.capability_name);
            dbms_output.put_line(v_capability.possible);
            dbms_output.put_line(v_capability.related_text);
            dbms_output.put_line(v_capability.msgtxt);
        end loop;
    end;
    /Edited by: ORA-01435 on Sep 30, 2009 12:54 PM

    That's what I thought too. As far as I'm concerned, this is perfectly acceptable. Of course I'm in 10g R2, but:
    http://download.oracle.com/docs/cd/B19306_01/server.102/b14223/basicmv.htm#sthref534
    I keep re-reading the rules, trying to see why it thinks I'm violating one of them. Might have to meta-link this one.
    Just ran this on a different box, ran fine. Seem to have configuration issues between the boxes.
    Edit: Just determined that the boxes that this doesn't work on have Oracle parameters for compatibility set to 10.1.0.2.0, I'll change them and check if it modifies behavior
    Edited by: ORA-01435 on Oct 1, 2009 7:44 AM

  • OJ syntax for multi-table left outer join with MS Oracle Driver

    I have a multi-table left outer join that works fine in SQL Server ODBC Driver, Oracle ODBC driver 8.01.07.00, but not with Microsoft ODBC Driver for Oracle 2.573.7326.0
    SELECT * from { oj A LEFT OUTER JOIN B ON A.col1 = B.col1 LEFT OUTER JOIN C ON A.col1 = C.col1 }
    I noticed someone had a similar problem (the proposed solution doesn't work):
    http://www.justpbinfo.com/listarchive/msg02874.html
    Does anyone know how to get this working with the Microsoft ODBC Driver for Oracle? Or does it just not work?

    The Microsoft ODBC Driver for Oracle 2.573.7326.0 does perform the same 'fix up' with {oj} in Oracle 8i. The problem is that it doesn't work when joining more than two tables:
    This works:
    SELECT * from { oj A LEFT OUTER JOIN B ON A.col1 = B.col1}
    This doesn't work:
    SELECT * from { oj A LEFT OUTER JOIN B ON A.col1 = B.col1 LEFT OUTER JOIN C ON B.col1 = C.col1 }
    (The second query will work with the Oracle Oracle ODBC driver, with a bit of tweaking. But I haven't found a way to get it to work with the Microsoft ODBC Driver for Oracle 2.573.7326.0. My suspicion is that it just doesn't work.)
    Gavin

  • Left Outer Join In OBIEE

    Hi,
    I have two Oracle tables in the physical layer: a fact table and a dimension table.
    The fact table (FACT_TBL) like this:
    CURR_MTH | PREV_MTH | CURR_GRADE | PREV_GRADE | CITY | VALUE
    Jun | May | B | A | X | 5
    Jun | May | A | A | Y | 10
    Jun | May | C | C | X | 15
    Jun | May | D | C | Y | 20
    And the dimension table (GRADE_TBL) like this:
    GRADE | GRADE_NAME
    A | A
    B | B
    C | C
    D | D
    I joined those two tables above in the physical layer using GRADE field. Then, I created a business model using those two tables. I want to create a 4x4 matrix report with PREV_GRADE as the first column and the CURR_GRADE accross to the right like this:
    CURR_MONTH PROMPT = Jun
    PREV_MONTH PROMPT = May
    CITY PROMPT = X
    PREV_GRADE | A | B | C | D |
    A | (null) | 5 | (null) | (null) |
    B | (null) | (null) | (null) | (null) |
    C | (null) | (null) | 15 | (null) |
    D | (null) | (null) | (null) | (null)|
    The problem is that I couldn't show all grade (A to D) in the PREV_GRADE column in that table. Every time I filter the CITY in the prompt to X, I always get only A and C. The B and D rows are suppressed. How do I achieve the left outer join that I wanted above? Thanks a lot for the help.

    hi,
    this can be done in BMM layer.
    select the required BMM model. Right click and select "Buisness Model Diagram" and "whole diagram" .
    now double click on the joining link and specify the type of join here. (assuming you have used "New Complex join" to join these tables).

  • More than Outer join

    I have records in a table:
    TASKS
    =====
    TASKID          TASKCD          
    1000          AD
    1001          AD
    1002          AD
    1010          EO
    1011          EO
    1012          EO
    1013          EO
    EOs tasks depends on AD tasks and we have this dependency relationship in other table:
    DEPTASKS
    TASKID          DEPID          DEPCD
    1010          1000          COMPLIES
    1011          1001          COMPLIES
    I need to display those AD tasks that does not have any record in DEPTASKS i.e taskid = 1002 as well
    as those that has record in DEPTASKS.I am able to get the those ADs using outer join that does not have entry in
    DEPTASKS i.e
    (select taskad.taskid adid, taskad.taskcd,taskeo.taskid eoid,taskeo.task_cd
    from tasks adtask,
    tasks eotask) adeo, deptasks
    where
    adeo.eoid = deptasks.taskid(+)
    and deptasks.dep-task-id(+) = adid
    Problem: I also have to use one more filter i.e
    where DEPCD = 'COMPLIES'
    I.E :
    adeo.eoid = deptasks.taskid(+)
    and deptasks.dep-task-id(+) = adid
    and DEPCD = 'COMPLIES'
    when I use this filter, it again filters those ADs which does not have records in DEPTASKS.
    Any suggestion how to control this scenerio.

    Any suggestion how to control this scenerio.Here's a suggestion to "control" this scenario.
    SQL> @test3
    SQL> --
    SQL> with tasks as (
      2    select 1000 as taskid, 'AD' as taskcd from dual union all
      3    select 1001, 'AD' from dual union all
      4    select 1002, 'AD' from dual union all
      5    select 1010, 'EO' from dual union all
      6    select 1011, 'EO' from dual union all
      7    select 1012, 'EO' from dual union all
      8    select 1013, 'EO' from dual),
      9  deptasks as (
    10    select 1010 as taskid, 1000 as depid, 'COMPLIES' as depcd from dual union all
    11    select 1011, 1001, 'COMPLIES'    from dual union all
    12    select 1013, 1002, 'DOESNOTCOMPLY' from dual)
    13  --
    14  select t.taskid as t_taskid, t.taskcd as t_taskcd,
    15         d.taskid as d_taskid, d.depid  as d_depid, d.depcd as d_depcd
    16  from tasks t, deptasks d
    17  where t.taskid = d.taskid(+)
    18  and d.depcd(+) = 'COMPLIES';
      T_TASKID T_TASKCD     D_TASKID    D_DEPID D_DEPCD
          1010 EO               1010       1000 COMPLIES
          1011 EO               1011       1001 COMPLIES
          1001 AD
          1002 AD
          1013 EO
          1000 AD
          1012 EO
    7 rows selected.
    SQL>
    SQL>HTH
    isotope

  • SQL7 to ORA9i problem w/ outer joins

    The information provided for the new release 9.2.0.1.7 of the Migration workbench explained that outer joins would be easier to convert with the added parse options. I have several stored procedures with outer joins that are still giving warning errors with the latest version. I have selected the parse options to generate Oracle 8i outer joins and have also left it unchecked. I continue to get the same errors for the outer joins. Here is an example of the join:
    (SELECT DISTINCT Product_tblProductRegion.ProductRegion_ID
    FROM Product_tblProductRegion LEFT JOIN Product_tblMaster ON Product_tblProductRegion.ProductRegion_ProductID = Product_tblMaster.Product_ID
    WHERE Product_tblMaster.Product_ID Is Null)
    Please let me know what information is needed to work through this problems.
    Thank you.

    Logged bug, Bug No: 3393782
    The workaround is to manually copy the ANSI Outer join from the TSQL to PLSQL. There appears to be a conflict between two fixes in the code, the ANSI join fix and the table function code, which is applicable to sqlserver 2k.
    Turloch

Maybe you are looking for