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?

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

  • 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))

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

  • 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.

  • 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.

  • Full outer join unexpected results

    Warning, long message - I've searched the forums and found nothing similar. I've cut out as much as possible. We have been given the following schema to work with:
    CREATE TABLE CALLS (
    TRUNKIN VARCHAR2 (10),
    TRUNKOUT VARCHAR2 (10),
    DURATION FLOAT)
    Here is some test data:
    insert into calls values(null, 'a', 3);
    insert into calls values(null, 'a', 2);
    insert into calls values('a', null, 1);
    insert into calls values(null, 'a', 0);
    insert into calls values(null, 'a', 0);
    insert into calls values(null, 'a', 7);
    insert into calls values(null, null, 0);
    This is horribly unnormalized, but basically this table represent phone calls. trunkin and trunkout represent the two ends, and duration is length of a call. While obviously every call has two ends, the nulls above represent ends we don't care about in this example.
    The goal is to end up with data that looks like this. In English, we want the in and out summary statistics for each trunk to be summarized into a single row. (Sorry, these are supposed to be columns, but they got wrapped, so I reposted them as rows):
    TRUNKIN a
    IN_CALLS_ATTEMPTED 1
    IN_CALLS_COMPLETED 1
    IN_AVERAGE_DURATION 1
    TRUNKOUT a
    OUT_CALLS_ATTEMPTED 5
    OUT_CALLS_COMPLETED 3
    OUT_AVERAGE_DURATION 4
    Indeed, with the data given above, these are the results returned with the query at the end of this message. However, when I changed the one non-null trunkin value to null, I got very strange results. First, I independently ran the two subqueries. The first of course returns no rows, the second returns 1 with the same out values above; this is exactly what I would expect. However, when I run the full query, I get **5** rows back, each with just the trunkout column set to "a" and **all** other columns set to null. This makes no sense to me. The 5 rows are obviously the 5 rows from the original data set where trunkout = "a", but I'm not full outer joining those; I'm full outer joining the result of the group by, which only has 1 row. But even given that I'm getting 5 rows back, shouldn't all five of those have the remaining out columns filled in with the values above?
    Here is the query:
    select
    from
    SELECT
    trunkin as trunk,
    COUNT(*) AS in_calls_attempted,
    SUM
    CASE
    WHEN duration > 0 THEN 1
    ELSE 0
    END
    ) AS in_calls_completed,
    SUM(duration)/
    SUM
    CASE
    WHEN duration > 0 THEN 1
    ELSE 0
    END
    ) AS in_average_duration
    FROM CALLS
    WHERE trunkin IS NOT NULL
    GROUP BY trunkin
    ) callsin
    full outer join
    SELECT
    trunkout as trunk,
    COUNT(*) AS out_calls_attempted,
    SUM
    CASE
    WHEN duration > 0 THEN 1
    ELSE 0
    END
    ) AS out_calls_completed,
    SUM(duration)/
    SUM
    CASE
    WHEN duration > 0 THEN 1
    ELSE 0
    END
    ) AS out_average_duration
    FROM CALLS
    WHERE trunkout IS NOT NULL
    GROUP BY trunkout
    ) callsout
    on callsin.trunk = callsout.trunk;

    I am not entirely sure why you are getting the results you are, but I strongly suspect that it is a result of outer joining on null columns. I would write the query as follows to avoid the outer join problem. The CASE statements in the outer query around the average duration calulations avoid the divide by zero error that would occur when some trunk has only in or out calls.
    SELECT trunk,SUM(in_calls_attempted) in_calls_attempted,
           SUM(in_calls_completed) in_calls_completed,
           CASE WHEN SUM(in_calls_completed) <> 0 THEN
                SUM(in_duration)/SUM(in_calls_completed)
                ELSE 0 END ave_in_duration,
           SUM(out_calls_attempted) out_calls_attempted,
           SUM(out_calls_completed) out_calls_completed,
           CASE WHEN SUM(out_calls_completed) <> 0 THEN
                SUM(out_duration)/SUM(out_calls_completed)
                ELSE 0 END ave_out_duration
    FROM (
       SELECT trunkin trunk,COUNT(*) in_calls_attempted,
              SUM(CASE WHEN duration > 0 THEN 1 ELSE 0 END) in_calls_completed,
              SUM(duration) in_duration,0 out_calls_attempted,
              0 out_calls_completed,0 out_duration
       FROM calls
       GROUP BY trunkin
       UNION ALL
       SELECT trunkout trunk,0 in_calls_attempted,0 in_calls_completed,
              0 in_duration,COUNT(*) out_calls_attempted,
              SUM(CASE WHEN duration > 0 THEN 1 ELSE 0 END) out_calls_completed,
              SUM(duration) out_duration
       FROM calls
       GROUP BY trunkout)
    GROUP BY trunkTTFN
    John

  • Do Outer Joins as well as Self Joins Affect the Performence of a Query ??

    4 Tables A,B,C,D.
    1 View V Based
    Each of the tables having 1 and only one primary key and a few NOT NULL columns.
    Now my Query selects from A,B,C,D,V with mapping Table A columns with all other Table(B,C,D,V) Primary Key Columns using Left Outer Join.
    Select A.a1,A.a2,A.a3,A.a4,B1.ba,B2.bb,B3.bc,B4.bd,C.c1,D.d1 from (((((((A left outer join B B1 on A.ba=B1.ba) left outer join B B2 on A.bb=B2.bb) left outer join B B3 on A.bc=B3.bc)left outer join B B4 on A.bd=B4.bd)left outer join C on A.c1=C.c1)left outer join D on A.d1=D.d1) left outer join V on A.v1 = V.v1) order by 1;
    In this case will the query design effect the Performence???... As this query is taking a long time. As for as Indexes are there on these tables only default Indexes due to Primary, Unique as well as Foreign key only.... Hence table structure is very simple and straight. I need a suggession in such a manner that without making changes to the Table (I am not even allowed to include a single Index to them) ...can the query be modified to optimise the performence??

    Each change to a query can effect the performance.
    Your query looks straight and simple. Maybe you could increase the performance by simply removeing the order by criteria.
    This requires a sort and a sort can be slow, especially when the resulting dataset is very large.
    If there are indexes on all foreign keys and you join using those FKs then there should be no problem with the index structure.
    I can't say whether it would be better to use an index or not. but you can look at the execution plan and check what the CBO wants to do.
    Make sure that all statistics are up to date. You could consider to run an additional dbms_stats.gather_table_stats with compute in the test environment, just to see if the execution plan changes after this.
    For further ideas search this forum for the thread "When your query takes too long".

  • Merging two complemental result sets... or OUTER JOINs not working?

    Dear experts!
    Again I have a very difficult problem for which I ask Your help, but this time I am better prepared than last time and can deliver sample data of my (hopefully not too much) simplified example:
    create table Subjects(
    pk_id          number          not null primary key,
    title          varchar2(128)
    create table People(
    pk_id          number          not null primary key,
    name          varchar2(128)
    create table Results(
    pk_id          number          not null primary key,
    fk_subjects_id     number,
    fk_people_id     number,
    result          number
    insert into Subjects(pk_id, title) values (1, 'Choosing a recipe')
    insert into Subjects(pk_id, title) values (2, 'Shopping ingredients')
    insert into Subjects(pk_id, title) values (3, 'Preparations')
    insert into Subjects(pk_id, title) values (4, 'Cooking for beginners')
    insert into Subjects(pk_id, title) values (5, 'Eating for pros')
    insert into Subjects(pk_id, title) values (6, 'Dishwashing for everyone')
    insert into Subjects(pk_id, title) values (7, 'Digesting for experts')
    insert into Subjects(pk_id, title) values (8, 'Becoming hungry again...')
    insert into Subjects(pk_id, title) values (9, 'Redo from start')
    insert into People(pk_id, name) values (1, 'Hank')
    insert into People(pk_id, name) values (2, 'Cloe')
    insert into People(pk_id, name) values (3, 'Mary')
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (1, 1, 1, 2)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (2, 2, 1, 4)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (3, 3, 1, 3)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (4, 9, 1, 5)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (5, 1, 2, 4)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (6, 2, 2, 1)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (7, 3, 2, 5)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (8, 4, 2, 2)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (9, 5, 2, 3)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (10, 6, 2, 2)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (11, 7, 2, 1)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (12, 4, 3, 3)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (13, 5, 3, 5)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (14, 7, 3, 1)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (15, 8, 3, 5)
    insert into Results(pk_id, fk_subjects_id, fk_people_id, result) values (16, 9, 3, 1)
    Please imagine this as an university for amateur cooks. Now I want to present them their performance record/"scorecard", for every student, only with her or his marks. On this performance record there should be a list of all 9 subjects possible to pass, and where students got a result, that result should be filled in. I thought that should be possible to achieve with something like this:
    SELECT PEOPLE.NAME, SUBJECTS.TITLE, RESULTS.RESULT FROM RESULTS
    JOIN PEOPLE ON PEOPLE.PK_ID = RESULTS.FK_PEOPLE_ID
    JOIN SUBJECTS ON SUBJECTS.PK_ID = RESULTS.FK_SUBJECTS_ID
    WHERE RESULTS.FK_PEOPLE_ID = 2
    But also using (LEFT|RIGHT|FULL) OUTER JOINs here does not help me to get what I want, I always only get
    NAME TITLE RESULT
    Cloe Choosing a recipe 4
    Cloe Shopping ingredients 1
    Cloe Preparations 5
    Cloe Cooking for beginners 2
    Cloe Eating for pros 3
    Cloe Dishwashing for everyone 2
    Cloe Digesting for experts 1
    But I want:
    NAME TITLE RESULT
    Cloe Choosing a recipe 4
    Cloe Shopping ingredients 1
    Cloe Preparations 5
    Cloe Cooking for beginners 2
    Cloe Eating for pros 3
    Cloe Dishwashing for everyone 2
    Cloe Digesting for experts 1
    Cloe Becoming hungry again...
    Cloe Redo from start
    Without having to fill in empty rows for all students which did not take all exams yet.
    Is it possible? If so, how?
    Thank You very much in advance and Happy Easter to everyone! :-)
    With kind regards,
    Chriss
    Edited by: user9355711 on 01.04.2010 07:01
    Edited by: user9355711 on 01.04.2010 07:28
    Edited by: user9355711 on 01.04.2010 07:29

    Also;
    var n number
    exec :n := 2;
    PL/SQL procedure successfully completed
    n
    2
    select ppl.name, sub.title, res.result
      from subjects sub, people ppl, results res
    where sub.pk_id = res.fk_subjects_id(+)
       and ppl.pk_id = :n
       and res.fk_people_id(+) = :n
    order by sub.title;
    NAME       TITLE                         RESULT
    Cloe       Becoming hungry again... 
    Cloe       Choosing a recipe                  4
    Cloe       Cooking for beginners              2
    Cloe       Digesting for experts              1
    Cloe       Dishwashing for everyone           2
    Cloe       Eating for pros                    3
    Cloe       Preparations                       5
    Cloe       Redo from start          
    Cloe       Shopping ingredients               1

  • View with outer join results wrong number of rows

    Hi,
    When i run a query on a view it returns 2 rows(2 distinct rows), when i run the same query with the select statement which the view is created , it returns only 1 row. According to data the 1 row result is correct, how come twi results. A coding sample as follows. Any help is most appreciated.
    I have a view created based on a outer join of two views in the format;
    create or replace view view1 as
    select ord.order_no order_no,
    ord.del_type del_type,
    det.qty qty
    from detail_view det, order_view ord
    where det.site(+) = ord.site
    and det.part(+) = ord.part
    and nvl(ord.del_type,'_NULL_') <> 'F'
    with read only;
    detail_view & order_view themselves have several group by/sum and union Alls.
    When i run the query on this view
    [Select * from View1 where order_no = 'A30' And del_type = 'B']
    it returns 2 distinct rows. But when i run the select statement which created the View1 with the query it returns only one row!!
    What did i do wrong?
    Thanks
    Sanjeewa

    I cannot reproduce this :
    SCOTT@LSC01> create table detail_view(qty number,site number,part number);
    Table created.
    SCOTT@LSC01> create table order_view(order_no varchar2(10), del_type varchar2(1), site number,part number);
    Table created.
    SCOTT@LSC01>
    SCOTT@LSC01> create or replace view view1 as
      2  select ord.order_no order_no,
      3  ord.del_type del_type,
      4  det.qty qty
      5  from detail_view det, order_view ord
      6  where det.site(+) = ord.site
      7  and det.part(+) = ord.part
      8  and nvl(ord.del_type,'_NULL_') <> 'F'
      9  with read only;
    View created.
    SCOTT@LSC01>
    SCOTT@LSC01> insert into order_view values ('A30','B',1,2);
    1 row created.
    SCOTT@LSC01> insert into order_view values ('A30','B',1,2);
    1 row created.
    SCOTT@LSC01>
    SCOTT@LSC01> Select * from View1 where order_no = 'A30' And del_type = 'B';
    ORDER_NO   D        QTY
    A30        B
    A30        B
    SCOTT@LSC01>
    SCOTT@LSC01> select ord.order_no order_no,
      2  ord.del_type del_type,
      3  det.qty qty
      4  from detail_view det, order_view ord
      5  where det.site(+) = ord.site
      6  and det.part(+) = ord.part
      7  and nvl(ord.del_type,'_NULL_') <> 'F' ;
    ORDER_NO   D        QTY
    A30        B
    A30        Bwhat is your version?

  • Case statement resulting into Left outer join with other tables

    Hi All ,
    I am facing a stuation where a Case statement on one of the logical columns in Answers is resulting into a left outer join with a table in the query.
    If we remove the case stmt, the table is not being acessed.
    The case stmt is a simple one and no other logical column is being accessed in the case stmt.
    Please advice .
    Thanks.

    Hi Sai,
    No ..we dont have any left outer join ...its just that I am selecting measure from F1 which has a confimred dimension D1 with F2.Now when I dont have case stmt on measure from F1(Case stmt is something like : CASE WHEN "- P table"."P Column" = 'Y' THEN 'Right' ELSE 'Wrong' END), then it doesnt query F2.
    However as soon as I introduce the case stmt ,the query creates a left outer join with F2.
    Thanks.

  • Strange result for outer join with rownum

    I'm using rownum in join condition of left outer join query but i'm getting strange results.
    Query is:
    Select * from table1 left outer join table2 on table1.id = table2.id or rownum=1
    Data in table1 is
    id
    7
    8
    9
    Data in table2 is
    id
    10
    11
    12
    Result of above query in Oracle 9.2.0.1 is
    table1.id table2.id
    7 10
    7 11
    7 12
    8 10
    8 11
    8 12
    9 10
    9 11
    9 12
    Even if change is rownum related condition to like rownum >2 even than i'm getting same result.
    In case of inner join, the above condition gives results as required.
    Can anybody explain the result or is it a bug?

    could you please explain why you are using rownum.
    You may have a look at the following link explaining rownum and you should understand why you got this result, keep in mind that you are using an OR condition.
    http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96540/sql_elements6a.htm#4295

  • How to merge 3 different query results using full outer join?

     Hi all This is my my query for 2 results
    with t1 as (
    select trans.crAcc_id,trans.cr_amt,row_number() over (order by trans.head_id) rn from Acttrans trans,
     Acttranhead head where trans.head_id in(select link_id from acttrans where head_id=12) and trans.crAcc_id!=0
     and head.head_id=trans.head_id
    t2 as (
    select trans.drAcc_id,trans.dr_amt,head.[Vouc_No],head.[Vouc_Date] ,head.[Check_No],head.[Check_Date],head.[stat],row_number() over (order by trans.head_id) rn from Acttrans trans,
     Acttranhead head where trans.head_id=12 and trans.drAcc_id!=0
     and head.head_id=trans.head_id
     select t1.crAcc_id, t1.cr_amt,t2.[Vouc_No],t2.[Vouc_Date] ,t2.[Check_No],t2.[Check_Date],t2.[stat],t2.drAcc_id,t2.dr_amt from t1
      full outer join t2 on t1.rn = t2.rn
    Query 3: SELECT [CrAcc_Id]  FROM [KSSDATA].[dbo].[ActTrans] where head_id=12 and crAcc_id!=0
    and i want to add Query3 result to the ABOVE RESULT but i am unable add third result using full outer join
    Thanks
    Balu D

    >>>but i am unable add third result using full outer join
    Do you get the error or wrong result?
    Best Regards,Uri Dimant SQL Server MVP,
    http://sqlblog.com/blogs/uri_dimant/
    MS SQL optimization: MS SQL Development and Optimization
    MS SQL Consulting:
    Large scale of database and data cleansing
    Remote DBA Services:
    Improves MS SQL Database Performance
    SQL Server Integration Services:
    Business Intelligence

  • ORA-30563, Outer Join not allowed in select list

    I can not find any information about this error message that I am getting.
    I have just upgraded my Oracle database from Version 7.3 to Version 8.1.7, a stored procedure that was written in v7.3 has outer joins in the select statement.
    when trying to run this proc in version 8 I get this meesage.(ORA-30563, Outer Join not allowed in select list)
    code ex:
    Select alt.id
    decode(alt.advise, NULL, NULL, AA.act_yr(+))||'-'||AA.act_per(+)||'-'||AA.Acc_per_no(+)) as advise_no
    from alt, AA;
    Is there any information about this message anywhere? or does anybody know if this is a known issue with oracle ver 8.1.7?
    Thanks
    CJ

    It appears to have been a bug in 7.x
    From a metalink note on bugs fixed in 8i (doc 132632.1)
    974742 Oracle does not report an error if (+) is specified in select-list. The OUTER JOIN operator (+) is only valid in WHERE clause predicates. As this is not flagged as an error the query can give unexpected results. The correct action to avoid this problem is to fix the query.
    Ken

Maybe you are looking for

  • How to do a 3rd party sales process

    How to do 3rd party sales process.....    plz reply me with the full configuration.....

  • " NOKIA X2 " How to Hide Files (Photos/Videos) fro...

    To All Nokia X2 Gallery Sufferers!!! I bought my NOKIA X2  over the weekend, and the problem of Hiding my files from the Gallery view has plagued me ever since I held this phone in my hand... The Gallery is excellent for certain things, and I quite l

  • Trying to find the location for getting started with hootbar

    I added the hootbar addon and on the information page about the addon it said you could go to the getting started page to find information on how to use hootbar but I can't locate the page

  • Why is YYYYMM date in flat file coming out in Preview as YYMMYY ?

    Hi, The date in the flat file is 200707 but when previewed, it comes up as 070720 I previewed a previous successful load and the data in the preview was 200706. I then copied the row and pasted it in Excel and saved as .CSV and then previewed this ne

  • View Filter

    I need help on a view filter. I tried it via view UI setting but does not work.  Then I am working in designer with the following code. I got an error when I open it in browser "Cannot complete this action. Please try again.". I appreciate if someone