Outer join condition

Hello

Scenario:
If tableA is related to the tableB, and then get all rows from tableA, excluding the lines in table B with col2 = 'P '.
If to tableB, tableA is not linked, then get all rows from tableA.
create table tableA as (
select '1' col1 from dual
union all
select '2' from dual
union all
select '3' from dual
union all
select '4' from dual
)

create table tableB as (
select 'A' Pkey, '1' col1, 'S' col2 from dual
union all
select 'B' Pkey, '2' col1, 'S' col2 from dual
union all
select 'E' Pkey, '2' col1, null col2 from dual
union all
select 'C' Pkey, '3' col1, null col2 from dual
union all
select 'D' Pkey, null col1, 'S' col2 from dual
union all
select 'F' Pkey, '3' col1, 'P' col2 from dual
)
select A.*, B.*
from tableA A, tableB B
where A.col1 = B.col1 (+)
--This is the output I need to get
1     A     1     S
2     B     2     S
2     E     2     (null)
3     C     3     (null)
3     F     3     P      --     <---- excluding this row
4     (null)     (null)     (null)
and to exclude this line, I added this to my request
and B.col2 (+) = 'S'
but after adding only at my request, the result became
1     A     1     S
2     B     2     S
3     (null)     (null)     (null)
4     (null)     (null)     (null)
Some of the fields that involve having a value becomes zero.
What I need to change to get the result I wanted above.


Thank you.

Published by: Spongebob 28 June 2011 19:08
with tableA as
(
select '1' col1 from dual
union all
select '2' from dual
union all
select '3' from dual
union all
select '4' from dual
),
tableB as (
select 'A' Pkey, '1' col1, 'S' col2 from dual
union all
select 'B' Pkey, '2' col1, 'S' col2 from dual
union all
select 'E' Pkey, '2' col1, null col2 from dual
union all
select 'C' Pkey, '3' col1, null col2 from dual
union all
select 'D' Pkey, null col1, 'S' col2 from dual
union all
select 'F' Pkey, '3' col1, 'P' col2 from dual
)
select A.col1 a_col1, B.pkey b_pkey, b.col1 b_col1, b.col2 b_col2
from tableA A, tableB B
where A.col1 = B.col1 (+)
  and nvl(b.col2,'S')='S';

Tags: Database

Similar Questions

  • Join with conditions of outer join statement

    Hello
    The following was extracted from the 11 GR 2 document guide performance, which I am not quite understand.
    Can anyone provide some examples to clearly explain this. Thank you

    For join instructions examples with outer join conditions, the table with the outer join operator must come after the other table in the condition in the join order. The optimizer does not consider join orders that violate this rule. Similarly, when a subquery was transformed into an antijoin or a semi-join, arrays of the subquery must come after these tables in the outer query to which they were connected or block in correlation. However, semijoins and antijoins of hash are override this order condition in certain circumstances
  • A left outer join

    create table test1 (col1 varchar2 (10));

    create table test2 (col1 varchar2 (10));

    Insert into test1 values('1');

    Insert into test1 values('2');

    Insert into test1 values('3');

    Insert into test2 values('1');

    Select * from test1, test2 where test1.col1 = test2.col1 (+) and test1.col1 = 1;

    Select * from test1 test2 outer join left on test1.col1 = test2.col1 and test1.col1 = 1;

    Why are these two different results?

    Hello

    user13648517 wrote:

    create table test1 (col1 varchar2 (10));

    create table test2 (col1 varchar2 (10));

    Insert into test1 values('1');

    Insert into test1 values('2');

    Insert into test1 values('3');

    Insert into test2 values('1');

    Select * from test1, test2 where test1.col1 = test2.col1 (+) and test1.col1 = 1;

    Select * from test1 test2 outer join left on test1.col1 = test2.col1 and test1.col1 = 1;

    Why are these two different results?

    In the first query, the condition

    test1.Col1 = 1

    is not part of the join condition.  The outer join is done first and then the lines where the test1.col1 <> 1 are deleted.

    In the second query, this condition is part of the join condition.  Test1 lines are not removed results just don't not outer join conditions.

    This shows one of the many benefits of the ANSI join syntax, especially when well formatted:

    Select *.

    of test1

    outer join test2 left test1.col1 = test2.col1

    and test1.col1 = 1;

    This clearly shows that the condition "test1.col1 = 1" is part of the join condition.

  • Doubt with OUTER JOIN behavior

    I thought I knew all about OUTER JOINS to this scenario. Can pls someone explain how Oracle behaves in the following SQL code:

    WITH t1 AS
    (SELECT 1 as empid from dual
    union all
    select 2 from dual),
    t2 as
    (select 1 as empid from dual)
    select *
    from t1 
    left outer join
    t2
    on (
    t1.empid = t2.empid AND t1.empid=2
    );
    

    Expected O/P

    EMPID EMPID_1
    2NULL VALUE

    Real O/P

    EMPID EMPID_1
    1NULL VALUE
    2NULL VALUE

    In this way...

    SQL > ed
    A written file afiedt.buf

    1 t1 WITH (SELECT empid from all double union 1
    2. Select 2 double),
    3 t2 (select 1 as double empid)
    4  --
    5 Select
    6 T1
    7 * a left outer join t2 (t1.empid = t2.empid) and t1.empid = 2
    SQL > /.

    EMPID EMPID
    ---------- ----------
    2
    1

    the "t1.empid = 2' is part of the OUTER JOIN condition.

    In this way...

    SQL > ed
    A written file afiedt.buf

    1 t1 WITH (SELECT empid from all double union 1
    2. Select 2 double),
    3 t2 (select 1 as double empid)
    4  --
    5 Select
    6 T1
    left outer join 7 t2 on (t1.empid = t2.empid)
    8 * where t1.empid = 2
    SQL > /.

    EMPID EMPID
    ---------- ----------
    2

    the "t1.empid = 2" belongs to the filtering conditions

    When it is part of the OUTER JOIN condition, he says that he should join t2 records where all conditions are met, otherwise the join should not be made, it does not say it to filter the overall results.

    Maybe this helps clarify...

    SQL > ed
    A written file afiedt.buf

    1 t1 WITH (SELECT empid from all double union 1
    2. Select 2 double),
    3 t2 (select empid Union 1 double all the)
    4. Select 2 of the double)
    5  --
    6 select *.
    7 T1
    8 * a left outer join t2 (t1.empid = t2.empid) and t1.empid = 2
    SQL > /.

    EMPID EMPID
    ---------- ----------
    2          2
    1

    Here we have 1 and 2 records in both tables, but the records in t2 are joined only where the record of t1 has an empid 2, so, although t2 has an empid 1, which is not reached because the join condition is not met.

  • Different Outer Join query result

    Hi all

    Under query gives the expected result


    Select DECODE (FPOVR. PROFILE_OPTION_VALUE,
    NULL, FPOVS. PROFILE_OPTION_VALUE, FPOVR. ZZ PROFILE_OPTION_VALUE)
    OPS FND_PROFILE_OPTIONS, FND_PROFILE_OPTION_VALUES FPOVR,.
    FND_PROFILE_OPTION_VALUES FPOVS where 1 = 1 and FPOVS. LEVEL_ID (+) = 10001
    and FPOVS. LEVEL_VALUE (+) = 0
    and FPOVS. PROFILE_OPTION_ID (+) IS FRENCH POLYNESIA. PROFILE_OPTION_ID
    and FPOVR. (+) LEVEL_ID = 10003 and FPOVR. LEVEL_VALUE (+) = 21533
    and FPOVR. PROFILE_OPTION_ID (+) IS FRENCH POLYNESIA. PROFILE_OPTION_ID
    and fpo.profile_option_name = 'GL_SET_OF_BKS_ID. '


    But the following query does not give the expected result.


    Select DECODE (FPOVR. PROFILE_OPTION_VALUE,
    NULL, FPOVS. PROFILE_OPTION_VALUE, FPOVR. ZZ PROFILE_OPTION_VALUE)
    OPS FND_PROFILE_OPTIONS, FND_PROFILE_OPTION_VALUES FPOVR,.
    FND_PROFILE_OPTION_VALUES FPOVS where 1 = 1 and FPOVS. LEVEL_ID (+) = 10001
    and FPOVS. LEVEL_VALUE (+) = 0
    and FPOVS. PROFILE_OPTION_ID (+) IS FRENCH POLYNESIA. PROFILE_OPTION_ID
    and FPOVR. (+) LEVEL_ID = 10003 and FPOVR. LEVEL_VALUE = 21533
    and FPOVR. PROFILE_OPTION_ID (+) IS FRENCH POLYNESIA. PROFILE_OPTION_ID
    and fpo.profile_option_name = 'GL_SET_OF_BKS_ID. '

    Difference between them is a join with external FPOVR. LEVEL_VALUE and hard coded value. Why these query above return different results even if the outer join is made with hard coded in value?

    Thank you
    SK

    SK says:
    Hi all

    Under query gives the expected result

    Select DECODE (FPOVR. PROFILE_OPTION_VALUE,
    NULL, FPOVS. PROFILE_OPTION_VALUE, FPOVR. ZZ PROFILE_OPTION_VALUE)
    OPS FND_PROFILE_OPTIONS, FND_PROFILE_OPTION_VALUES FPOVR,.
    FND_PROFILE_OPTION_VALUES FPOVS where 1 = 1 and FPOVS. LEVEL_ID (+) = 10001
    and FPOVS. LEVEL_VALUE (+) = 0
    and FPOVS. PROFILE_OPTION_ID (+) IS FRENCH POLYNESIA. PROFILE_OPTION_ID
    and FPOVR. (+) LEVEL_ID = 10003 and FPOVR. LEVEL_VALUE (+) = 21533
    and FPOVR. PROFILE_OPTION_ID (+) IS FRENCH POLYNESIA. PROFILE_OPTION_ID
    and fpo.profile_option_name = 'GL_SET_OF_BKS_ID. '

    But the following query does not give the expected result.

    Select DECODE (FPOVR. PROFILE_OPTION_VALUE,
    NULL, FPOVS. PROFILE_OPTION_VALUE, FPOVR. ZZ PROFILE_OPTION_VALUE)
    OPS FND_PROFILE_OPTIONS, FND_PROFILE_OPTION_VALUES FPOVR,.
    FND_PROFILE_OPTION_VALUES FPOVS where 1 = 1 and FPOVS. LEVEL_ID (+) = 10001
    and FPOVS. LEVEL_VALUE (+) = 0
    and FPOVS. PROFILE_OPTION_ID (+) IS FRENCH POLYNESIA. PROFILE_OPTION_ID
    and FPOVR. (+) LEVEL_ID = 10003 and FPOVR. LEVEL_VALUE = 21533
    and FPOVR. PROFILE_OPTION_ID (+) IS FRENCH POLYNESIA. PROFILE_OPTION_ID
    and fpo.profile_option_name = 'GL_SET_OF_BKS_ID. '

    Difference between them is a join with external FPOVR. LEVEL_VALUE and hard coded value.

    In fact, the difference is that the condition relating to FPOVR. LEVEL_VALUE to 21533 is part of the outer join condition in the first query, but it is not in the second query.

    Why these query above return different results even if the outer join is made with hard coded in value?

    When you say

    FPOVR.LEVEL_VALUE(+) = 21533
    

    (with a sign +) only the lines of fpovr with level_value = 21533 will join the other table. If there is no such line in fpovr, then a row of output will be generatedd for each row in the other table anyway.
    When you say

    FPOVR.LEVEL_VALUE = 21533
    

    (without a sign +) then the outer join is made using the other conditions, which may result in some lines of the other table who appear in the result set with NULL in places where the values of fpovr would normally appear. Then when the join is complete, the condition is applied, and all these lines with the NULL value instead of fpovr.level_value are deleted because they do not meet the condition "FPOVR. LEVEL_VALUE = 21533 ". The effect is identical to an inner join.

    When you use the old rating of outer join (i.e. with signs +), if any condition involving the fpovr table has a + sign, and then all of the conditions involving table fpovr must have a + sign, otherwise the result will be the same if none of the conditions were a sign +.

  • outer join: difference between two queries

    Below two queries which should give the same results in my opinion. I want that all records of u_protocol and the pval.u_protocol_variable_value value if necessary.

    Why the outer join in query2 does not work as in query1?


    Query1:
    select p.u_protocol_id, i.u_protocol_variable_value
    from lims_sys.u_protocol p,
    (
       select pval.u_protocol_id, pval.u_protocol_variable_value
       from lims_sys.u_protocol_variable pvar, lims_sys.u_protocol_value_user pval
       where pvar.u_protocol_variable_id = pval.u_protocol_variable_id
       and pvar.name = 'VALUE_Protocol_Group'
    ) i   
    where p.u_protocol_id  = i.u_protocol_id (+)
    Query2:
    select prt.u_protocol_id, pval.u_protocol_variable_value
    from lims_sys.u_protocol prt, lims_sys.u_protocol_variable pvar, lims_sys.u_protocol_value_user pval
    where pvar.u_protocol_variable_id = pval.u_protocol_variable_id
    and prt.u_protocol_id = pval.u_protocol_id (+)
    and pvar.name = 'VALUE_Protocol_Group'

    Hello

    When you perform an outer join, all conditions on the tables in option must be outer join conditions. Otherwise, the effect is an inner join.
    There is one exception: cascade of outer joins, external-junction b of a and c is outside attached to b. In this case, in the b - c join only columns of c are marked with the sign +.

    Re - write to obtain the same results as query1, query2 like this:

    select  prt.u_protocol_id
    ,      pval.u_protocol_variable_value
    from     lims_sys.u_protocol          prt
    ,      lims_sys.u_protocol_variable     pvar
    ,      lims_sys.u_protocol_value_user pval
    where     pvar.u_protocol_variable_id (+)     = pval.u_protocol_variable_id     -- cascading outer join
    and     prt.u_protocol_id           = pval.u_protocol_id (+)
    and     pvar.name (+)               = 'VALUE_Protocol_Group'     -- (+) added
    ;
    

    I find the syntax ANSI easier to use for all the joins and much easier for outer joins.

  • Outer join on the Filter Condition

    Hello

    I would like to show all rows in a query for two conditions to filter on the 'status '. I used an outer join on the outer query to return the values inside the inline query, but it returns not to return all rows.

    create table (test)
    ID number,
    start_date date,
    status varchar2 (1).
    number of amount,
    number of cust_type
    );


    Insert test values (001, June 1, 2014 ", am ', 189, 78");
    Insert test values (001, March 26, 2014 ", 'R', 175, 4");
    Insert test values (001, December 1, 2014 ", 'R', 89, 91");
    Insert test values ("001, 13 August 2014 ', 'J', 19, 2);
    Insert test values (001, 12 August 2014 ', 'E', 19, 2);

    Insert test values (002, January 1, 2014 ', 'R', 17, 4);
    Insert test values (002, 26 June 2014 ", 'R', 175, 4");
    Insert test values (' 002, February 1, 2014 ', 'J', 9, 8);
    Insert test values (002, 13 October 2014 ', ', 190, 2);

    Insert test values (' 003, June 1, 2014 ', 'J', 189, 78);
    Insert test values (003, March 26, 2014 ", 'R', 175, 4");
    Insert test values (003, December 1, 2014 ", 'R', 89, 91");
    Insert test values (' 003, 13 August 2014 ', 'J', 19, 2);
    Insert test values (' 003, 12 August 2014 ', 'J', 19, 2);

    commit;

    Select i.ids, i.start_date, i.cust_type, i.amount as gross_amount, i.amount + ii.amount as net_amount
    test I have,
    (select id, amount)
    of the test
    where (status = status or 'R' = 'J')) ii
    where i.cust_type in (4, 78, 91, 2, 4, 8)
    and i.ids (+) = ii.ids
    and i.status (+) to (', 'E')
    "and i.start_date between 1 January 14 ' and 31-dec-2014."

    The query above exclude ID 003 because there is that no status (M / E) butI want always display all codes, even if the condition is not consistent

    Hello

    Want results from an inner join to match identifiers, but the results of an outer join for identifiers that are not?  In other words, you want to include the rows of the table I only when one of the following is true:

    The line of table I have ticked all the boxes, or

    No line in not table i with the same ID meets all conditions

    ?

    If so, here's a way to do it:

    WITH got_rnk AS

    (

    Select i.ids, i.start_date, i.cust_type

    , nvl2 (ii.ids, i.amount, 0) as gross_amount

    , i.amount + nvl (ii.amount, 0) as net_amount

    dense_rank () over (partition of i.ids

    order of nvl2 (ii.ids, 'A', 'B')

    ) as rnk

    I have test

    (in left outer join

    SELECT ID, amount

    of the test

    where status ('R', 'J')

    ) ii on i.ids = ii.ids

    and i.cust_type in (4, 78, 91, 2, 4, 8)

    and i.start_date between to_date (January 1, 2014 ", 'dd-mon-yyyy')

    and to_date (31-dec-2014', 'dd-mon-yyyy')

    and i.status in (', 'E')

    )

    SELECT ID, start_date, cust_type

    gross_amount, net_amount

    of got_rnk

    where rnk = 1

    ;

    Results of your sample data:

    ID START_DATE GROSS_AMOUNT NET_AMOUNT CUST_TYPE

    --------- ----------- ---------- ------------ ----------

    1 1 June 2014 78 189 364

    1 1 June 2014 78 189 278

    1 1 June 2014 78 189 208

    1 12 August 2014 2 19 38

    1 12 August 2014 2 19 108

    1 12 August 2014 2 19 194

    2 13 October 2014 2 190 207

    2 13 October 2014 2 190 365

    2 13 October 2014 2 190 199

    3 March 26, 2014 4 0 175

    3 1 June 2014 78 0 189

    3 12 August 2014 2 0 19

    3 August 13, 2014 2 0 19

    3 1 December 2014 91 0 89

  • Outer joins and null in the 'where' clause condition

    Hi people,

    Please help me on this.

    Here's my query.

    with x

    (select 'a' as a dual union all col1)

    Select 'b' as col1 of union double all the

    Select 'c' as double col1

    ),

    y as

    (

    Select 'b' as col2 from dual Union all the

    Select 'c' as col2 from dual Union all the

    Select would be "as col2 from dual Union all the"

    Select 'e' as col2 from dual

    )

    Select * x y right outer join

    on x.col1 = y.col2 and y.col2 is null

    Get all the lines of 'COL1' as null. Why like this?

    Just add the condition to the WHERE clause for example

    WITH x AS
    (SELECT 'a' AS col1 FROM dual UNION ALL
    SELECT 'b' AS col1 FROM dual UNION ALL
    SELECT 'c' AS col1 FROM dual
    ),
    y AS
    (
    SELECT 'b' AS col2 FROM dual UNION ALL
    SELECT 'c' AS col2 FROM dual UNION ALL
    SELECT 'd' AS col2 FROM dual UNION ALL
    SELECT 'e' AS col2 FROM dual
    )
    SELECT * FROM x LEFT OUTER JOIN y
    ON x.col1=y.col2                     ----want to add "and y.col2 is null " condition to get value "a"
    where y.col2 is null
    
  • Conditional outer join

    I have question while doing a conditional outer join... Suggestion help will be most appreciated

    I have three tables say x, y, emp.
    Table x and have a foreign key for emp say name empid column.

    condition should now be like that...
    If x.empid is not null
    then
    x.EmpID = emp.empid
    If x.empid is null
    then
    If y.empid is not null
    then
    y.EmpID = emp.empid
    on the other
    y.EmpID = emp.empid (+)

    To solve this problem, I pulled following gives the error "ORA-01719: outer join operator (+) not allowed in GOLD or IN the operand.
    Select *.
    x qm, o q, stdqs of the emp
    where)
    (qm.empid is not null and qm.empid = stdqs.empid)
    or
    (qm.empid is null and q.empid = stdqs.empid (+))
    )

    Published by: 870965 on July 9, 2012 12:36

    Published by: 870965 on July 9, 2012 12:37 AM

    a possible solution:

    WITH y AS
         (SELECT 10 AS y_pk, NULL AS empid FROM DUAL
          UNION ALL
          SELECT 20, 60 FROM DUAL
          UNION ALL
          SELECT 30, NULL FROM DUAL
         ),
         x AS
         (SELECT 1 AS x_pk, 10 AS y_fk, 50 AS empid FROM DUAL
          UNION ALL
          SELECT 2, 20, NULL FROM DUAL
         ),
         emp AS
         (SELECT 50 empid, 'Tom' empname FROM DUAL
          UNION ALL
          SELECT 60 empid, 'Smith' empname FROM DUAL
         )
    SELECT
         *
    FROM
         (SELECT
               x.x_pk
              ,y.y_pk
              ,nvl(x.empid, y.empid) empid
          FROM
              x, y
          WHERE x.y_fk(+) = y.y_pk
         ) z
         ,emp
    WHERE
         z.empid = emp.empid(+);
    

    Published by: kedruwsky on July 9, 2012 02:44

  • outer join and OR condition

    Hello world

    I have a query that is not working properly. I'm trying to join two tables and I or condition and outer join
    I get the error message
     ORA-01719: outer join operator (+) not allowed in operand of OR or IN
    
    my query is as follow
    
    SELECT l.* FROM table1 l, table2 map
    WHERE (NVL(l.id, '-99') = NVL(map.id(+), NVL(l.id, '-99'))
            AND  l.TYPE = 'TKE')
          ) OR 
        (NVL(l.id, '-99') = NVL(map.id(+), NVL(l.id, '-99'))
    AND NVL(l.type, '-99') = NVL(map.type(+), NVL(l.type, '-99'))
    AND NVL(l.pos_22, '-99') = NVL(map.pos_22(+),NVL(l.pos_22, '-99'))
    AND NVL(l.pos_27, '-99') = NVL(map.pos_27(+),NVL(l.pos_27, '-99'))
    AND NVL(l.pos_17, '-99') = NVL(map.pos_17(+),NVL(l.pos_17, '-99'))
    AND NVL(l.pos_18, '-99') = NVL(map.pos_18(+),NVL(l.pos_18, '-99'))
    AND NVL(l.pos_12, '-99') = NVL(map.pos_12(+),NVL(l.pos_12, '-99'))
    AND NVL(l.pos_16, '-99') = NVL(map.pos_16(+),NVL(l.pos_16, '-99'))
    AND NVL(l.pos_34, '-99') = NVL(map.pos_34(+),NVL(l.pos_34, '-99'))
    AND NVL(l.pos_43, '-99') = NVL(map.pos_43(+),NVL(l.pos_43, '-99'))
    AND NVL(l.pos_14, '-99') = NVL(map.pos_14(+),NVL(l.pos_14, '-99'))
    AND NVL(l.status_cd, '-99') = NVL(map.status(+),NVL(l.status_cd, '-99'))
    AND NVL(l.action_cd,'-99') = NVL(map.action_cd(+), NVL(l.action_cd,'-99'))
    AND NVL(l.sys,'-99') = NVL(map.sys(+), NVL(l.sys,'-99'))
    AND NVL(l.ind,'-99') = NVL(map.ind(+), NVL(l.ind,'-99'))
      )
    So, basically in the above query I say that if the type = "TKE" do not join on all columns of pos. If type is not TKE then do all the joints on all columns POS etc.
    How do I rewrite query so that I can use OR and the outer JOIN in the same query?

    Hello

    It is one of several good reasons to use the ANSI join syntax. Move all the join conditions in the clause on, not the WHERE clause, and you do not use the sign +.

    SELECT  l.*
    FROM           table1 l
    LEFT OUTER JOIN  table2 map  ON   (    NVL(l.id, '-99') = COALESCE (map.id, l.id, '-99')
                                        AND  l.TYPE = 'TKE'
                          )
                                 OR  (     NVL (l.id, '-99') = COALESCE (map.id, l.id, '-99')
                              AND   NVL (l.type, '-99') = COALESCE (map.type), l.type, '-99')
                         ...
    

    Instead of nesting the NVL statements, use COALESCE, as illustrated above. It is independent of the issue of the join.

  • Bug with an outer join, or &amp; Analytics function (or rownum)

    Hello

    Seems to be a combination of an outer join, OR and rownum confuses the CBO.

    First request is without rownum, the second is with rownum.

    The second query expects 203 t lines and never ends. It should behave the same as query 1, with 24 M lines.

    Remove the GOLD clause query 2 allows him to behave as a query 1, with 24 M lines.

    We never saw it? Is there a solution?

    SELECT *
      FROM message i
      LEFT JOIN (SELECT hi.message_id, hi.update_dt
                   FROM message_hist hi) h ON (t.id = h.master_id
                                           AND(t.update_dt = h.update_dt OR h.update_dt <TO_DATE('150901','RRMMDD')));
          
    -----------------------------------------------------------------------------------------------                                                                                                                                                                                                              
    | Id  | Operation           | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                                                                                                                              
    -----------------------------------------------------------------------------------------------                                                                                                                                                                                                              
    |   0 | SELECT STATEMENT    |                         |    24M|    13G|   475G  (2)|999:59:59 |                                                                                                                                                                                                              
    |   1 |  NESTED LOOPS OUTER |                         |    24M|    13G|   475G  (2)|999:59:59 |                                                                                                                                                                                                              
    |   2 |   TABLE ACCESS FULL | MESSAGE                 |  8037K|  1318M| 29883   (2)| 00:06:59 |                                                                                                                                                                                                              
    |   3 |   VIEW              |                         |     3 |  1302 | 59136   (2)| 00:13:48 |                                                                                                                                                                                                              
    |*  4 |    TABLE ACCESS FULL| MESSAGE_HIST            |     3 |   168 | 59136   (2)| 00:13:48 |                                                                                                                                                                                                              
    -----------------------------------------------------------------------------------------------                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                 
    Predicate Information (identified by operation id):                                                                                                                                                                                                                                                          
    ---------------------------------------------------                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                 
       4 - filter("I"."MESSAGE_ID"="HI"."MESSAGE_ID" AND                                                                                                                                                                                                                                                         
                  ("HI"."UPDATE_DT"<TO_DATE('150901','RRMMDD') OR "I"."UPDATE_DT"="HI"."UPDATE_DT"))     
    ----------------              
    SELECT *
      FROM message i
      LEFT JOIN (SELECT hi.message_id, hi.update_dt
                      , ROWNUM
                   FROM message_hist hi) h ON (t.id = h.master_id
                                           AND(t.update_dt = h.update_dt OR h.update_dt <TO_DATE('150901','RRMMDD')));
         
    -------------------------------------------------------------------------------------------------                                                                                                                                                                                                            
    | Id  | Operation             | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                                                                                                                            
    -------------------------------------------------------------------------------------------------                                                                                                                                                                                                            
    |   0 | SELECT STATEMENT      |                         |   203T|   112P|   475G  (2)|999:59:59 |                                                                                                                                                                                                            
    |   1 |  NESTED LOOPS OUTER   |                         |   203T|   112P|   475G  (2)|999:59:59 |                                                                                                                                                                                                            
    |   2 |   TABLE ACCESS FULL   | MESSAGE                 |  8037K|  1318M| 29883   (2)| 00:06:59 |                                                                                                                                                                                                            
    |   3 |   VIEW                |                         |    25M|    10G| 59151   (2)| 00:13:49 |                                                                                                                                                                                                            
    |*  4 |    VIEW               |                         |    25M|    10G| 59151   (2)| 00:13:49 |                                                                                                                                                                                                            
    |   5 |     COUNT             |                         |       |       |            |          |                                                                                                                                                                                                            
    |   6 |      TABLE ACCESS FULL| MESSAGE_HIST            |    25M|  1355M| 59151   (2)| 00:13:49 |                                                                                                                                                                                                            
    -------------------------------------------------------------------------------------------------                                                                                                                                                                                                            
                                                                                                                                                                                                                                                                                                                 
    Predicate Information (identified by operation id):                                                                                                                                                                                                                                                          
    ---------------------------------------------------                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                 
       4 - filter("I"."MESSAGE_ID"="H"."MESSAGE_ID" AND ("I"."UPDATE_DT"="H"."UPDATE_DT" OR                                                                                                                                                                                                                          
                  "H"."UPDATE_DT"<TO_DATE('150901','RRMMDD')))         
     
    

    RowNum in a subquery is supposed to ensure that the subquery is evaluated completely before filtering, otherwise, how could you go out rownum?

    Your question is compounded because of the join condition that forces a level of nested loops, which means that the table should be fully analysed once for each line of conduct rowsource. You can either transform the join in an equijoin and allow a hash to run, or you join could materialize the subquery once.

    Allow the hash join:

    SELECT count (*)

    Message FROM

    LEFT JOIN (SELECT hi.message_id, hi.update_dt

    ROWNUM

    OF message_hist salvation) PM ON (i.message_id = h.message_id

    AND i.update_dt = h.update_dt)

    LEFT JOIN (SELECT hi.message_id, hi.update_dt

    ROWNUM

    OF message_hist salvation) h2 ON (i.message_id = h2.message_id

    AND h2.update_dt<>

    AND h2.update_dt <> i.update_dt)

    /

    ----------------------------------------------------------------------------------------

    | ID | Operation | Name | Lines | Bytes | Cost (% CPU). Time |

    ----------------------------------------------------------------------------------------

    |   0 | SELECT STATEMENT |              |     1.    66.   211 (1) | 00:00:01 |

    |   1.  GLOBAL TRI |              |     1.    66.            |          |

    |*  2 |   EXTERNAL RIGHT HASH JOIN |              |   800 | 52800 |   211 (1) | 00:00:01 |

    |*  3 |    VIEW                 |              |     1.    22.    70 (0) | 00:00:01 |

    |   4.     COUNTY |              |       |       |            |          |

    |   5.      TABLE ACCESS FULL | MESSAGE_HIST |     1.    22.    70 (0) | 00:00:01 |

    |*  6 |    EXTERNAL RIGHT HASH JOIN |              |   800 | 35200.   141 (1) | 00:00:01 |

    |   7.     VIEW                |              |     1.    22.    70 (0) | 00:00:01 |

    |   8.      COUNTY |              |       |       |            |          |

    |   9.       TABLE ACCESS FULL | MESSAGE_HIST |     1.    22.    70 (0) | 00:00:01 |

    |  10.     TABLE ACCESS FULL | MESSAGE |   800 | 17600 |    70 (0) | 00:00:01 |

    ----------------------------------------------------------------------------------------

    Information of predicates (identified by the operation identity card):

    ---------------------------------------------------

    2 - access("I".") MESSAGE_ID '= 'H2'.' MESSAGE_ID "(+))"

    filter ("H2". "UPDATE_DT" (+)<>'I'. " ("' UPDATE_DT")

    3 - filter("H2".") UPDATE_DT "(+)<>

    6 - access("I".") "UPDATE_DT" ="H" UPDATE_DT "(+) AND"

    "I"." ' MESSAGE_ID ' ="H" MESSAGE_ID "(+))"

    Materialize the subquery:

    WITH h AS (SELECT / * + MATERIALIZE * / hi.message_id, hi.update_dt)

    ROWNUM

    OF message_hist salvation)

    SELECT count (*)

    Message FROM

    LEFT JOIN: ON (i.message_id = h.message_id

    AND (i.update_dt = h.update_dt OR h.update_dt<>

    ----------------------------------------------------------------------------------------------------------

    | ID | Operation | Name                        | Lines | Bytes | Cost (% CPU). Time |

    ----------------------------------------------------------------------------------------------------------

    |   0 | SELECT STATEMENT |                             |     1.    22.  1740 (0) | 00:00:01 |

    |   1.  TRANSFORMATION OF THE TEMPORARY TABLE.                             |       |       |            |       |

    |   2.   LOAD SELECT ACE | SYS_TEMP_0FD9D6810_5B8F6E67 |       |       |            |       |

    |   3.    COUNT                   |                             |       |       |            |       |

    |   4.     TABLE ACCESS FULL | MESSAGE_HIST |     1.    22.    70 (0) | 00:00:01 |

    |   5.   GLOBAL TRI |                             |     1.    22.            |       |

    |   6.    NESTED EXTERNAL LOOPS |                             |   800 | 17600 |  1670 (0) | 00:00:01 |

    |   7.     TABLE ACCESS FULL | MESSAGE |   800 | 17600 |    70 (0) | 00:00:01 |

    |   8.     VIEW                   |                             |     1.       |     2 (0) | 00:00:01 |

    |*  9 |      VIEW                  |                             |     1.    22.     2 (0) | 00:00:01 |

    |  10.       TABLE ACCESS FULL | SYS_TEMP_0FD9D6810_5B8F6E67 |     1.    22.     2 (0) | 00:00:01 |

    ----------------------------------------------------------------------------------------------------------

    Information of predicates (identified by the operation identity card):

    ---------------------------------------------------

    9 - filter("I".") ' MESSAGE_ID ' ="H" MESSAGE_ID' AND ('I'. "" "UPDATE_DT"="H" UPDATE_DT' OR

    "H"." UPDATE_DT ".<>

    You may need to change the first condition to make sure that you select the correct subquery.

    -edit

    Not able to view a plan but you can invade the second join condition select and then the result of a subquery with a predicate according to your requirement. This should delay the or rating and leave only an equijoin (although rowsource return may be slightly larger than the opposite).

    -Second edition, it did not work exactly when I tried it.

    A hybrid of the previous two plans with a slight modification of how he was imitating the GOLD:

    WITH h AS (SELECT / * + MATERIALIZE * / hi.message_id, hi.update_dt)

    ROWNUM Clotilde

    OF message_hist salvation)

    SELECT i.MESSAGE_ID

    i.UPDATE_DT

    COALESCE(h.message_id,h2.message_id) message_id

    , COALESCE (h.update_dt, h2.update_dt) update_dt

    Clotilde COALESCE (h.rown, h2.rown)

    Message FROM

    LEFT JOIN: ON (i.message_id = h.message_id

    AND i.update_dt = h.update_dt)

    LEFT JOIN: h2 WE (DECODE(h.message_id,,i.message_id) = h2.message_id - only try this if previous join returned NULL

    AND h2.update_dt<>

    /

    --------------------------------------------------------------------------------------------------------
    | ID | Operation | Name                      | Lines | Bytes | Cost (% CPU). Time |
    --------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT |                           |     1.    66.     8 (0) | 00:00:01 |
    |   1.  TRANSFORMATION OF THE TEMPORARY TABLE.                           |       |       |            |          |
    |   2.   LOAD SELECT ACE | SYS_TEMP_0FD9D6605_28F27F |       |       |            |          |
    |   3.    COUNT                   |                           |       |       |            |          |
    |   4.     TABLE ACCESS FULL | MESSAGE_HIST |   150.  3300 |     2 (0) | 00:00:01 |
    |   5.   GLOBAL TRI |                           |     1.    66.            |          |
    |*  6 |    EXTERNAL RIGHT HASH JOIN |                           | 10497.   676K |     6 (0). 00:00:01 |
    |*  7 |     VIEW                   |                           |   150.  3300 |     2 (0) | 00:00:01 |
    |   8.      TABLE ACCESS FULL | SYS_TEMP_0FD9D6605_28F27F |   150.  3300 |     2 (0) | 00:00:01 |
    |*  9 |     OUTER HASH JOIN |                           |   328. 14432 |     4 (0) | 00:00:01 |
    |  10.      TABLE ACCESS FULL | MESSAGE |   200 |  4400 |     2 (0) | 00:00:01 |
    |  11.      VIEW                  |                           |   150.  3300 |     2 (0) | 00:00:01 |
    |  12.       TABLE ACCESS FULL | SYS_TEMP_0FD9D6605_28F27F |   150.  3300 |     2 (0) | 00:00:01 |
    --------------------------------------------------------------------------------------------------------

    Information of predicates (identified by the operation identity card):
    ---------------------------------------------------

    6 - access("H2".") MESSAGE_ID "(+) = DECODE (TO_CHAR ('H'". "))" MESSAGE_ID"), NULL, 'I '. (("' MESSAGE_ID '))
    7 - filter("H2".") UPDATE_DT "(+)<>
    9 - access("I".") "UPDATE_DT" ="H" UPDATE_DT "(+) AND 'I'." "" ' MESSAGE_ID '="H" MESSAGE_ID "(+))"

    (This plan is another system if costs are not comparable)

  • left and right outer join

    Hi gurus,

    Left outer join:

    -------------------

    Select * from A LEFT OUTER JOIN B on A.col = B.col;

    by definition, a left outer join brings the rows that match the join condition and lines not corresponding to table A.

    My question here is "corresponding to B and no matching rows in A" is that nothing, but... SELECT * FROM A;

    can someone pls clarity...

    Thank you.

    Imagine that you had:

    TableA

    COLUMN1 COLUMN2

    'A'                1

    'B'                2

    'C'                3

    TABLEB

    COLUMN1 COLUMN2

    'A'                 'X1'

    'A'                 'X2'

    'B'                 'Y'

    'D'                 'Z'

    SELECT * FROM TABLEA;

    A 1

    B 2

    C 3

    Now, if you want to join (first column is either in table A or B, (deuxieme from tableA, third table B)

    SELECT * FROM TABLEA A JOIN TABLEB B ON (A.COLUMN1 = B.COLUMN1)

    A 1 X 1

    A 1 X 2

    B 2 Y

    SELECT * FROM TABLE LEFT B EXTERNAL ON (A.COLUMN1 = B.COLUMN1) JOIN TABLE

    A 1 X 1

    A 1 X 2

    B 2 Y

    C 3 {null}

    SELECT * FROM TABLE A TABLE RIGHT OUTER JOIN B (A.COLUMN1 = B.COLUMN1)

    A 1 X 1

    A 1 X 2

    B 2 Y

    D {null} Z

    SELECT * FROM TABLE A TABLE FULL OUTER JOIN B (A.COLUMN1 = B.COLUMN1)

    A 1 X 1

    A 1 X 2

    B 2 Y

    C 3 {null}

    D {null} Z

    HTH

  • Need help with outer join

    Hello

    I have a requirement in which I need to get data from a third table where a date of the third table is higher than a date in the second array.

    Ex:

    SELECT t1.column1, t3.column2
    FROM t1, t2, t3
    WHERE t1.id = t2.foreign_id
    AND t1.id ( + ) = t3.foreign_id
    AND t3.some_date_column > t2.another_date_column
    
    

    However, using the query above returns no results if the date condition is not met. I still need to show t1.column1 and a null t3.column2.

    How should I do this?

    Thank you

    Allen

    Edit: Added information about the requirement.

    Hi Allen

    1. SELECT t1.column1, t3.column2
    2. T1, t2, t3
    3. WHERE t1.id = t2.foreign_id
    4. AND t1.id = t3.foreign_id (+)
    5. AND t3.some_date_column (+) > t2.another_date_column

    I guess that this t1.column1 must not be null. Or am I wrong? The + sign must be placed on the side where draws are accepted. You must repeat it for each condition on the table.

    Alternativlely you can use the LEFT OUT JOIN syntax. If the two columns are allowed null you need a FULL OUTER JOIN.

    BTW: The join to t2 is not required if a refefernce constraint forced.

  • Left Outer Join DR.

    Hi Experts,

    I have a requirement that says - see the chart for the past 10 days, regardless the presence data table in fact.
    Lets consider an example - Time_dim product, are my dimension tables, Purchase_Order is my fact table.

    I did it for external Purchase_Order in left RPD with TIME_DIM and inner join with the PRODUCT table.  and execution of query of exit-
    Select T.Date, P.item, count (distinct PO.order_no)
    TIME_DIM t, PRODUCT P, PURCHASE_ORDER PO
    where T.date_key = PO.date_key
    and P.item = in. agenda
    and P.item = 'laptop ';

    The query generated by OBIEE left outer join, but when the condition P.item = "Notebook" included in the query, and if there are no orders for this product in one of the date, that date will not come in the result set.

    the query to be generated by the OBIEE is-


    Select T.Date, PO.item, count (distinct PO.order_no)
    TIME_DIM t,.
    (SELECT P.ITEM, IN. ORDER_NO
    PRODUCT P, PO PURCHASE_ORDER
    WHERE P.item = in. agenda
    and P.item = 'Laptop') IN.
    WHERE T.date_key = PO.date_key (+);

    How to design the RPD to achieve this. All pray to advise on this. Thanks in advance.

    Thank you
    Chantal

    Hello

    You are on 11.1.1.7?

    I would say that your condition can be made without using external and maintenance of product and the standard between the FACT dimension, time inner join join.

    If you enable your property analysis OBIEE "Include Null values" will automatically return all the elements of time and product matching your filter (so you'll need to add a filter on 'Date' to limit it to the last 10 days or you will have a unique day of your time dimension).

    If you filter then on "Laptop", even if there is not a single value in order for "Laptop" in the last 10 days, he will be there on the screen.

    Easy, clean and you keep your inner join between the facts and Dimensions.

    Take a look at this example, I just did on SampleApp 406:

    Selection of 12 months (year 2010) and a customer (id = 89) and income. The model has only an inner join. I activate the option "Include Null values" and here is the result.

    A line with cells only empty because there is not a single revenue for customer 89 in 2010. This is exactly your condition.

    Honestly, do not touch your model using the outer join, you will have more side effects than benefits. Every single scan will do the outer join and you'll have a lot of data 'empty' return of the DB (more large data set containing just the null values) and probably you need the outer join in 15 to 25% of your analysis.

    Keep things simple, it will be faster and easier to maintain.

  • Why left outer join with a table gives me more lines?

    Hi gurus,

    I can see "view_a" and a table 'table_a '.

    view_a a county of 100 lines. Now, when I left outer join that discovers with a 'table_a', I expect all 100 lines.

    However, I'm more than 100 lines. Is it still possible?

    Also even to analyze these situations, how can I move forward?

    Because it is very high volumn of sight and takes longer to run.

    Select count (*) view_a, view_b

    where view_a.col1 = view_b.col1 (+)

    and view_a.col2 = view_b.col2 (+);

    Thank you

    I can see "view_a" and a table 'table_a '.

    view_a a county of 100 lines. Now, when I left outer join that discovers with a 'table_a', I expect all 100 lines.

    However, I'm more than 100 lines. Is it still possible?

    Also even to analyze these situations, how can I move forward?

    Because it is very high volumn of sight and takes longer to run.

    Select count (*) view_a, view_b

    where view_a.col1 = view_b.col1 (+)

    and view_a.col2 = view_b.col2 (+);

    Which is not necessarily related to the use of an outer join.

    Just join of two tables in general will give you more rows of one table has.

    Scott DEPT table contains ONE row for deptno = 10

    The EMP table has THREE rows of deptno = 10

    The number of rows you plan if you join two tables using an equi-join?

    Three - what is MORE lines the DEPT table has for deptno = 10

    Select * from Department where deptno = 10

    DEPTNO, DNAME, LOC
    10, ACCOUNTING, NEW YORK

    Select * from emp where deptno = 10

    MGR, EMPLOYMENT ENAME, EMPNO, HIREDATE, SAL, COMM, DEPTNO
    7782, CLARK, MANAGER, 7839, 6/9/1981,2450, 10
    7839, KING, PRESIDENT, 17 NOVEMBER 00, 10
    7934, MILLER, CLERK, 7782, 23 JANUARY 00: 10

    Select dept.*, emp.*
    Department, emp
    where dept.deptno = 10
    and dept.deptno = emp.deptno

    DEPTNO, DNAME, LOC, EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO_1
    10, ACCOUNTING, NEW YORK, 7782, CLARK, MANAGER, 7839, 6/9/1981,2450, 10
    10, ACCOUNTING, NEW YORK, 7839, KING, PRESIDENT, 17 NOVEMBER 00, 10
    10, ACCOUNTING, NEW YORK, 7934, MILLER, CLERK, 7782, 23 JANUARY 00: 10

    So if these are the lines ONLY in the table EMP and DEPT the query would give you THREE lines despite the DEPT table only ONE line.

    No do you expect? You get ALL the child rows that belong to the parent company. Otherwise, how could it possibly work?

    The OUTER join includes lines where the parent row exists but there is NO child line as others have shown.

    Outer joins

    Outer join extends the result of a simple join. Outer join returns all rows that satisfy the join condition and also returns some or all rows in a table for which no line of the other meet the join condition.

    Get more lines to exist in one of the paintings is a basic necessity. It usually has NOTHING to with the question of whether you have an outside to join or not.

    See the section on the JOINTS in the Oracle documentation

    http://docs.Oracle.com/CD/B28359_01/server.111/b28286/queries006.htm

Maybe you are looking for