Left Join with a subquery

Hey everybody!

I have some difficulty in trying to create a SQL query.

I have the following tables:

-Table Products: Product list
CREATE TABLE (PRODUCTS)
PRODUCT_ID INTEGER NOT NULL,
KEY ("PRODUCT_ID") PRIMARY CONSTRAINT 'PK_PRODUCTS '.
);

-Orders table: Decreed this product
CREATE TABLE ORDERS)
ORDER_ID INTEGER NOT NULL,
PRODUCT_ID INTEGER NOT NULL, / * FK PRODUCTS (PRODUCT_ID) * /.
KEY ("ID_PEDIDO") PRIMARY CONSTRAINT 'PK_ORDERS '.
);

-Orders_Approval table: register when an order is approved
CREATE TABLE ORDERS_APPROVAL)
ORDER_ID INTEGER NOT NULL, / * FK ORDERS (ORDER_ID) * /.
APPROVAL_DATE DATE NOT NULL,
USER_ID INTEGER,
KEY("ORDER_ID","APPROVAL_DATE") PRIMARY CONSTRAINT 'PK_ORDERS_APPROVAL '.
);

-Table Orders_ApprovalData: Register more details on the amenities of the order
CREATE TABLE ORDERS_APPROVAL_DETAILS)
APPROVALDET_ID INTEGER NOT NULL,
ORDER_ID INTEGER NOT NULL, / * FK ORDERS_APPROVAL (ORDER_ID) * /.
APPROVAL_DATE DATE NOT NULL, / * FK ORDERS_APPROVAL (APPROVAL_DATE) * /.
KEY ("APPROVALDET_ID") PRIMARY CONSTRAINT 'PK_ORDERS_APPROVAL_DETAILS '.
);

The thing is that an order may OU cannot be approved. Thus, there could be no record of an order in ORDERS_APPROVAL.

In addition, an order can have more than one approval.

Here is the data that I use:

/===========\
| PRODUCTS |
|===========|
| PRODUCT_ID |
|===========|
| 1.
|===========|
| 2.
|===========|
| 3.
\===========/

/========================\
| ORDERS |
|========================|
| ORDER_ID | PRODUCT_ID |
|===========|============|
| 27. 1.
|===========|============|
| 28. 2.
|===========|============|
| 29. 3.
\===========|============/

/=========================================\
| ORDERS_APPROVAL |
|=========================================|
| ORDER_ID | APPROVAL_DATE | USER_ID.
|===========|================|============|
| 27. 01/10/2009 | 56.
|===========|================|============|
| 27. 04/10/2009 | 96.
|===========|================|============|
| 29. 03/10/2009 | 77.
\===========|================|============/

/=============================================\
| ORDERS_APPROVAL_DETAILS |
|=============================================|
| APPROVALDET_ID | ORDER_ID | APPROVAL_DATE |
|================|===========|================|
| 1. 27. 01/10/2009 |
|================|===========|================|
| 2. 27. 04/10/2009 |
|================|===========|================|
| 3. 29. 03/10/2009 |
\================|===========|================/
I need to create a query that returns the data in all tables, but for orders with more than one certification,
the query must return only the last record. It is also necessary return orders that have not yet been approved.

My first query looked like this:

SELECT
*
Of
ORD IN ORDERS,
PRODUCT PROD,
ORDERS_APPROVAL ORDAPPROV,
ORDERS_APPROVAL_DETAILS ORDAPPDET
WHERE
PROD. PRODUCT_ID = DSB. PRODUCT_ID
AND ORDAPPROV. ORDER_ID (+) IS DSB. ORDER_ID
AND ORDAPPDET. ORDER_ID (+) IS ORDAPPROV. ORDER_ID
AND ORDAPPDET. DATA_APPROVAL_DATE (+) IS ORDAPPROV. APPROVAL_DATE

PS: I use the Oracle 8 syntax because it's the server I'll use. In addition, I can't change the design of database.

This query returns the data in table all. Because I used LEFT JOIN "(+)" to join the table orders_approval with the orders table, I am able to see even the orders with no approval.

But this way, I see also two approvals for order 27 (with the data above, this order was approved twice). I need to reach my paintings in the last approval for each order is but should be a left join so I can see the orders with no approval.

I tried this way:

SELECT
*
Of
ORD IN ORDERS,
PRODUCT PROD,
ORDERS_APPROVAL ORDAPPROV,
ORDERS_APPROVAL_DETAILS ORDAPPDET
WHERE
PROD. PRODUCT_ID = DSB. PRODUCT_ID
AND ORDAPPROV. ORDER_ID (+) IS DSB. ORDER_ID
--Also added the line below
AND ORDAPPROV. APPROVAL_DATE = (SELECT MAX (APPROVAL_DATE) OF ORDERS_APPROVAL WHERE THE ORDER_ID = ORDAPPROV. ORDER_ID)
AND ORDAPPDET. ORDER_ID (+) IS ORDAPPROV. ORDER_ID
AND ORDAPPDET. DATA_APPROVAL_DATE (+) IS ORDAPPROV. APPROVAL_DATE

But in this way, as I am specifying I want only records with approval equal to date at the latest for each order, I do not see the order without approval.

I tried again, with a left join like this:

SELECT
*
Of
ORD IN ORDERS,
PRODUCT PROD,
ORDERS_APPROVAL ORDAPPROV,
ORDERS_APPROVAL_DETAILS ORDAPPDET
WHERE
PROD. PRODUCT_ID = DSB. PRODUCT_ID
AND ORDAPPROV. ORDER_ID (+) IS DSB. ORDER_ID
--Also added the line below
AND ORDAPPROV. APPROVAL_DATE (+) = (SELECT MAX (APPROVAL_DATE) OF ORDERS_APPROVAL WHERE THE ORDER_ID = ORDAPPROV. ORDER_ID)
AND ORDAPPDET. ORDER_ID (+) IS ORDAPPROV. ORDER_ID
AND ORDAPPDET. DATA_APPROVAL_DATE (+) IS ORDAPPROV. APPROVAL_DATE

But I get a syntax error. Oracle said that it is not possible to do a join with a subquery.

If anyone knows how I can bring all this data?

Thanks in advance.

Published by: user9936895 on 05/10/2009 09:42: tried to fix the predetermined data schema.

Hello

Welcome to the forum!

A scalar, such as subquery

(SELECT MAX(APPROVAL_DATE) FROM ORDERS_APPROVAL WHERE ORDER_ID=ORDAPPROV.ORDER_ID)

is allowed in a WHERE clause, but not as a condition of outer join, as you discovered.

A workaround is the query expression so that it is not part of the outer join condition, which invlove in May (as in this case), adding another subquery. In the following query, the table of orders_approval in your original OF Division is replaced with online view, which uses the exact same scalar subquery in the WHERE clause. The online display will only contain one line per order_id (assuming that there is no link with for last approval_date).

SELECT
     *
FROM
     orders               ord,
     products          prod,
     (     -- Begin in-line view ORDAPPROV of last approval_date only
     SELECT     *       -- or list the columns needed in main query
     FROM     orders_approval         oa
     WHERE     approval_date = (
                    SELECT  MAX (approval_date)
                    FROM     orders_approval
                    WHERE     order_id     = oa.order_id
                    )
     )                ordapprov,
     orders_approval_details ordappdet
WHERE
     prod.product_id               = ord.product_id
AND     ordapprov.order_id (+)          = ord.order_id
AND     ordappdet.order_id (+)          = ordapprov.order_id
AND     ordappdet.approval_date (+)     = ordapprov.approval_date
;

Thank you for including CREATE TBAL statements; It is very useful.
You want to be even more useful in the future? Post INSERT statements for the sample data. That will make it easier for people to respond and easier for them to test their ideas.

Tags: Database

Similar Questions

  • Left join with three-table join query

    I am trying to create a query that left me speechless. Most of the query is simple enough, but I have a problem I do not know how to solve.

    Background:
    We have stock stored in i_action.

    We have the attributes available for each type of action. The attributes available for each action are described in shared_action_attribute. Each type of action can have three attributes or none at all.

    We have the values stored for the attributes in i_attribute_value.

    An example says:
    We have a transfer action (action_code B4). The action of B4 entry into i_action records the fact that the transfer took place and the date at which he spoke. The attributes available for a transfer action are the function code receiver, the receiving unit number and the reason of transfer code. These types of attributes available and their order are stored in shared_action_attribute. The actual values of the attributes for a specific action of transfer are stored in i_attribute_value.

    Now i_action and i_attribute_value can be connected directly in action_seq in i_action and ia_action_seq in i_attribute_value. A left join on these two tables provides results for all actions (including actions that have no attributes) and assign values (see Query 1 below).

    There are two questions. First of all, I want only the first two attributes. To specify the attributes of the first two, I also i_attribute_value a link to shared_action_attribute (which is where the order is stored). I can build a simple query (without the left join) which connects the three tables, but then shares without attributes would be excluded from my result (see Query 2 below).

    The second problem is that I'd actually a row returned for each action with first_attribute and second_attribute in the form of columns instead of two lines.

    The final query will be used to create a materialized view.

    Here are the tables and examples of what is stored in the:

    TABLE i_action
    Name Type
    ----
    ACTION_SEQ NUMBER (10)
    DATE OF ACTION_DATE
    ACTION_CODE VARCHAR2 (3)
    VARCHAR2 (1) DELETED

    EXAMPLE OF LINES
    ACTION_SEQ ACTION_DATE DELETED ACTION_CODE
    ----
    45765668 9 OCTOBER 09 B2 HAS
    45765670 9 OCTOBER 09 BA HAS
    45765672 B6 9 OCTOBER 09A
    45765673 9 OCTOBER 09 B4 HAS
    45765674 9 OCTOBER 09 G1 HAS
    45765675 9 OCTOBER 09 M3 HAS

    TABLE i_attribute_value
    Name Type
    ---
    IA_ACTION_SEQ NUMBER (10)
    SACTATT_SACT_CODE VARCHAR2 (3)
    SACTATT_SAT_TYPE VARCHAR2 (3)
    VARCHAR2 VALUE (50)

    EXAMPLE OF LINES
    IA_ACTION_SEQ SACTATT_SACT_CODE SACTATT_SAT_TYPE VALUE
    ----
    45765668 B2 COA 37 B
    45765670 BA ROA D
    45765670 BA ROR P
    45765672 B6 CAT C
    B4 45765673 RFC E
    45765673 B4 TRC P
    B4 45765673 RUN 7
    45765674 G1 SS 23567
    G1 45765674 ASG W

    TABLE shared_action_attribute
    Name Type
    ---
    SACT_CODE VARCHAR2 (3)
    SAT_TYPE VARCHAR2 (3)
    ORDER NUMBER (2)
    TITLE VARCHAR2 (60)

    EXAMPLE OF LINES
    SACT_CODE SAT_TYPE UNDER THE ORDER
    ----
    B2 ACO 1 Office code
    BA ROR 1 reason to re-open
    Authority of BA ROA 2 reopen
    B6 CAT 1 category
    B4 RFC 1 reception function code
    B4 RUN 2 receives the unit code
    B4 TRC 3 transfer of reason code
    Sequence of G1 SS 1 personal
    Reason for G1 ASG 2 assignment

    QUERY 1:
    It's my current query as well as its results. Most are select simple but only one column is filled using the function analytic last_value (thank you guys). The last column in the view sub stores the value of the attribute. What I want is to replace this single column with two columns named first_attribute and second_attribute and eliminate all other attributes.
    SELECT ia.action_seq, ia.action_date, ia.action_code cod,
    NVL
    (LAST_VALUE (CASE
    WHEN ia.action_code = "G1".
    AND iav.sactatt_sat_type = 'SS '.
    THEN THE VALUE
    WHEN ia.action_code IN ('A0', 'A1')
    THEN '67089'
    END IGNORE NULLS
    ) OVER (PARTITION BY ia.ici_charge_inquiry_seq ORDER BY ia.action_date,
    IA.serial_number, ia.action_seq),
    '67089'
    ) staff_seq,.
    value
    From i_action LEFT JOIN i_attribute_value iav AI
    ON iav.ia_action_seq = ia.action_seq
    WHERE ia.deleted = 'A ';

    ACTION_SEQ ACTION_DA COD STAFF_SEQ VALUE
    ----
    45765668 9 OCTOBER 09 B2 67089 37 B
    45765670 9 OCTOBER 09 BA D 67089
    45765670 9 OCTOBER 09 BA 67089 P
    45765672 9 OCTOBER 09 B6 67089 C
    45765673 9 OCTOBER 09 B4 67089 E
    45765673 9 OCTOBER 09 B4 67089 P
    45765673 9 OCTOBER 09 67089 7 B4
    45765674 9 OCTOBER 09 23567 23567 G1
    45765674 9 OCTOBER 09 G1 23567 W
    45765675 9 OCTOBER 09 M3 23567

    QUERY 2:
    This query is limited to the first two attributes but he also filed actions which have no attributes, and it creates still several lines for each action instead of a single line with two columns for attributes.
    SELECT ia.action_seq, ia.action_date, ia.action_code cod,
    NVL
    (LAST_VALUE (CASE
    WHEN ia.action_code = "G1".
    AND iav.sactatt_sat_type = 'SS '.
    THEN THE VALUE
    WHEN ia.action_code IN ('A0', 'A1')
    THEN '67089'
    END IGNORE NULLS
    ) OVER (PARTITION BY ia.ici_charge_inquiry_seq ORDER BY ia.action_date,
    IA.serial_number, ia.action_seq),
    '67089'
    ) staff_seq,.
    value
    OF shared_action_attribute saa, ims_action AI, ims_attribute_value iav
    WHERE iav.ia_action_seq = ia.action_seq
    AND iav.sactatt_sact_code = saa.sact_code
    AND iav.sactatt_sat_type = saa.sat_type
    AND saa.display_order IN ('1 ', ' 2')
    AND ia.deleted = 'A ';

    ACTION_SEQ ACTION_DA VALUE OF COD
    ----
    45765668 9 OCTOBER 09 B2 67089 37 B
    45765670 9 OCTOBER 09 BA D 67089
    45765670 9 OCTOBER 09 BA 67089 P
    45765672 9 OCTOBER 09 B6 67089 C
    45765673 9 OCTOBER 09 B4 67089 E
    45765673 9 OCTOBER 09 67089 7 B4
    45765674 9 OCTOBER 09 23567 23567 G1
    45765674 9 OCTOBER 09 G1 23567 W

    I found it quite complex to try to write - I hope that I was clear.

    Thank you very much!

    Hello

    You can use an alias for column (such as staff_seq) in the ORDER BY. Unfortunately, it's the only place where you can use it in the same query, where it was defined.
    You can use it anywhere in the super-requetes, however, so you can still work around this problem in assigning the aliases in a subquery and GROUP BY (or other) in a Super query, like this:

    WITH   ungrouped_data      AS
    (
        SELECT ia.action_seq, ia.action_date, ia.action_code,
              NVL
                  (LAST_VALUE (CASE
                                  WHEN ia.action_code = 'G1'
                                   AND sactatt_sat_type = 'SS'
                                     THEN VALUE
                                  WHEN ia.action_code IN ('A0', 'A1')
                                     THEN '67089'
                               END IGNORE NULLS
                              ) OVER (PARTITION BY ia.ici_charge_inquiry_seq ORDER BY ia.action_date, ia.action_seq),
                   '67089'
                  )staff_seq,
               (CASE
                  WHEN display_order = '1'
                  THEN VALUE
               END) first_attribute,
               (CASE
                  WHEN display_order = '2'
                  THEN VALUE
               END) second_attribute
          FROM i_action ia
          LEFT JOIN i_attribute_value iav
               ON iav.ia_action_seq = ia.action_seq
          LEFT JOIN shared_action_attribute
               ON sactatt_sact_code = sact_code
             AND sactatt_sat_type = sat_type
         WHERE ia.deleted = 'A'
    )
    SELECT       action_seq
    ,       action_date
    ,       action_code
    ,       staff_seq
    ,       MIN (first_attribute)          AS first_attribute
    ,       MIN (second_attribute)     AS second_attribute
    FROM       ungrouped_data
    GROUP BY  action_seq
    ,       action_date
    ,       action_code
    ,       staff_seq
    ;
    

    There are other alternatives for special cases, but none of them work in this particular case.

  • LEFT JOIN increases the number of lines

    Hi guys,.

    I had a problem, my left join retrieves multiple values. I know he has only 252 in there that correspond to the place where

    condition. If I use the table in a left join with the same condition where my row count increases.

    -1176 lines

    Select count (erg_ID) of

    MySchema. T_STA_ERG sta_erg

    INNER JOIN T_MEN hoechst

    ON sta_erg. PARAMETER = hoechst. PARAMETER

    AND sta_erg. JAHR = 2014

    where sta_erg. MESSERG_KNG = 'A' AND sta_erg. MESSERG_ALPHA IN ('03 ") and sta_erg. NORM_MESS is null

    -252 lines

    Select distinct erg_ID myschema. T_STA_ERG sta_erg where sta_erg. MESSERG_KNG = 'A' AND sta_erg. MESSERG_ALPHA IN ('03 ") and sta_erg. NORM_MESS is null

    any clue´s how I can build in conditions in my join which would not increase the results of the line?

    Why not just an inner join then?

  • Left join on 3 tables

    I have 3 tables to know

    CUREPRESSMASTER,
    CUREBLDGMACHINECONDITION,
    NAMINGMASTER

    with the structure of each table as
    CUREPRESSMASTER: -.
    CUREPRESS CHAR (5)
    PRESSTYPE TANK (8)
    CURINGGROUP CHAR (2)

    examples of data
    "CUREPRESS" "PRESSTYPE'"CURINGGROUP ".
    'M02' "HAM OF 63.5" "31".
    "M03" "HAM OF 63.5" "31".
    "M04" "HAM OF 63.5" "31".
    "M05" "HAM OF 63.5" "31".
    "M06" "63.5" "31".
    "M07" "HAM OF 63.5" "31".
    "S03" "63.5" "31".
    "S04" "HAM OF 63.5" "31".
    "S05" "HAM OF 63.5" "31".

    CUREBLDGMACHINECONDITION: -.
    GROUPID (2) TANK
    MACHINENAME CHAR (5)
    DATA01 CHAR(10)
    DATA02 CHAR(10)
    Samples: -.

    'GROUPID' "MACHINENAME" "DATA01" "DATA02.
    '30' 'M03' "63.5" "UNDER".
    '30' 'M04""63.5""UNDER ".
    '30' 'M05""63.5""UNDER ".
    '30' 'M06""63.5""UNDER ".
    '30' 'M07""63.5""UNDER ".
    "30" "M08" "63.5" "UNDER".

    NAMINGMASTER: -.
    IETS1 CHAR (1)
    CLASSEMENT2 CHAR (2)
    CERTIFICATE3 TANK (2)
    NAMING2 CHAR (10)

    Samples: -.
    "IETS1" "CLASSEMENT2" "CERTIFICATE3'"NAMING2 ".
    "0' '52" "31" "281".
    '0' '69' "31" "110".
    '2' '30' "31" "TBR".
    "3' '30'"31""TIRE PLANT. "
    "0' '51" "31" "261".
    "A" "30" "31" "RP".
    "A" "31" "31" "RP".
    "H'" ""31""MTRLBhind. "
    "J"     "01"     "31"     ""
    "L"     "01"     "31"     ""
    "G"     " "     "31"     ""
    "8" "" "31" "CambioMedi."

    Now, I want to have all the rows of the table CUREPRESS left join with two other tables as specified below.
    CUREPRESSMASTER. CUREPRESS = CUREBLDGMACHINECONDITION. MACHINENAME
    CUREPRESSMASTER. CURINGGROUP = NAMINGMASTER. CERTIFICATE3.

    Now I want to select the following columns as CUREPRESS, PRESSTYPE, NAMING2, DATA01 DATA02 after leaving the joints as shown above and curepress as primary key.

    When I tried using a General left join she gave much more duplicate rows.
    I have 100 lines in curepress, then I would have only 100 lines in the final result but I get my as 233 lines output, this may be due to CUREPRESSMASTER. CURINGGROUP = NAMINGMASTER. Certificate3 this condition.

    Please suggest me some queries.

    This may be due to CUREPRESSMASTER. CURINGGROUP = NAMINGMASTER. Certificate3 this condition.

    Yes. Because the above join result in one-to-MANY relationship. Look at your data

    CUREPRESS PRESSTYPE CURINGGROUP
    --------- --------- -----------
    M02       63.5 HAM  31
    M03       63.5 HAM  31
    M04       63.5 HAM  31
    M05       63.5 HAM  31
    M06       63.5      31
    M07       63.5 HAM  31
    S03       63.5      31
    S04       63.5 HAM  31
    S05       63.5 HAM  31          
    
     9 rows selected 
    
    CLASSIFICATION1 CLASSIFICATION2 CLASSIFICATION3 NAMING2
    --------------- --------------- --------------- ----------
    0               52              31              281
    0               69              31              110
    2               30              31              TBR
    3               30              31              TIRE PLANT
    0               51              31              261
    A               30              31              PSR
    A               31              31              PSR
    H                               31              MTRLBhind
    J               01              31
    L               01              31
    G                               31
    8                               31              CambioMedi 
    
     12 rows selected 
    

    The value is 31 for all rows in the table two. And so 9 * 12 output will be 108 lines. Its one expected result how you expect to only 9 lines?

    You can show us your results as well. I guess you are missing some basic business requirements. Show us your results.

  • Using Left Outer Join with reference

    I have three tables.
    Table 1: BOOK_DETAILS
    Fields: BOOK_ID, BOOK_NAME

    Table 2: BOOK_ISSUE_RECORD
    Fields: BOOK_ID, USER_NAME

    Table 3: BOOK_AUTHOR
    Fields: BOOK_ID, AUTHOR_NAME

    I must link table 1 and table 2 with a left outer join, because even if the book is not the questions to anyone, his name should come.
    I have once again display the name of the author of books for each book.
    I am able to create a query with the left outer join between table 1 and table 2. However, I am not able to give a reference to Table 3.
    Can someone help me with this please.

    Concerning
    Hawker
    select  d.book_name,
            a.book_author,
            i.user_name
      from       book_details d
            join
                 book_author a
              on (d.book_id = a.book_id)
            left join
                 book_issue_recors i
              on (d.book_id = i.book_id)
    /
    

    SY.

  • Left Outer Join with sum

    Dear elders,



    Firstly, sorry if my question is considered to be 'very novice' but I have this problem of confusion.

    Can I use the left outer join with summary?
    For example:

    Work table
    JobCode      JobGroupCode      
    111A         1100              
    112B         1100               
    113C         1100
    121A         1200
    333F         3300               
    Table No.
    JobGroupCode    ParentCode
    1100            1000
    1200            1000
    1300            1000
    3300            3000
    Activity table
    Jobcode      Mandays
    111A         5
    112B         7
    113C         3
    I want to choose with this result
    Job.JobCode    Job.JobGroupCode     JobGroup.Parentcode       Mandays
    111A           1100                 1000                      5
    112B           1100                 1000                      7               
    113C           1100                 1000                      3
    121A           1200                 1000                      0
    333F           3300                 3000                      0
    All I did was:
    select j.jobcode, j.jobgroupcode, jg.parentcode, sum(a.mandays)
      from job j
     inner join jobgroup jg on j.jobgroupcode = jg.jobgroupcode
      left join activity a on j.jobcode = a.jobcode
     group by j.jobcode, j.jobgroupcode, jg.parentcode
    and I got was only jobcode activity table, not exactly what I want to get all the work table jobcode. Could you please tell me, where I was wrong?

    result
    Job.JobCode    Job.JobGroupCode     JobGroup.Parentcode       Mandays
    111A           1100                 1000                      5
    112B           1100                 1000                      7               
    113C           1100                 1000                      3
    Thank you very much.

    Published by: user11197113 on May 25, 2009 03:31

    Published by: user11197113 on May 25, 2009 03:32

    Hello (and welcome!).

    Edit

    OK, try this:

    select j.jobcode, j.jobgroupcode, jg.parentcode, NVL(sum(a.mandays),0)
      from job j
     inner join jobgroup jg on j.jobgroupcode = jg.jobgroupcode
      left join activity a on j.jobcode = a.jobcode
     group by j.jobcode, j.jobgroupcode, jg.parentcode
    

    That will give you this:

    JOBC JOBG PARE SUM(A.MANDAYS)
    ---- ---- ---- --------------
    111A 1100 1000              5
    112B 1100 1000              7
    113C 1100 1000              3
    121A 1200 1000              0
    333F 3300 3000              0
    

    These are real results of your test data.

  • Do not repeat with a LEFT JOIN QUERY question

    Hello

    I would like to know how to display the following results:
    *Name*:  John Fox
    *Sales:*  1- LAPTOP
                    2- HARDDRIVE
                    3- COMPUTER
    Here's my 2 tables: CUSTOMER and SALES
    CUSTOMER
    _________________
    
    ID NAME GENDER 
    1 John Mayer F 
    2 Melissa John F 
    3 Julie Black F 
    4 Mickael Fox M 
    5 John Fox M 
    
    SALES
    _________________________
    ID ID_CUSTOMER TYPE 
    1 1 Boat 
    2 1 TV 
    3 4 CD PLAYER 
    4 5 LAPTOP 
    5 5 HARDDRIVE 
    6 5 COMPUTER 
     
    My QUERY
    SELECT customer.Name as NAME, customer.Gender, sales.TYPE
    from customer
    LEFT JOIN sales
    ON customer.ID = sales.ID_CUSTOMER
    WHERE customer.Name = 'John Fox'
    The problem: if I use the default template, I have:
    NAME GENDER TYPE 
    John Fox M LAPTOP 
    John Fox M HARDDRIVE 
    John Fox M COMPUTER 
    I don't want the name of John Fox being repeated in each row.
    I tried to add: #Name # in the DEFINITION of the REGION - REGION HEADER, but I have this result:
    #NAME# 
    NAME GENDER TYPE 
    John Fox M LAPTOP 
    John Fox M HARDDRIVE 
    John Fox M COMPUTER 
     
    So, what can I do to get this result? Change the query?
    Name:  John Fox
    Sales: 1- LAPTOP
           2- HARDDRIVE
            3- COMPUTER
    Thank you

    Roseline

    Roseline salvation,

    You can adapt the solution suggested in this post Re: more than 1 records in a single cell

    Thank you
    Manish

  • Left join of the two tables and multiple values into a single value separated by commas

    Hello

    I have following tables with their structures and their data as below.

    CREATE TABLE 'BETODI '. "" BETINFO ".

    (

    VARCHAR2 (8 BYTE) "CURRENTPRESS."

    ENABLE 'TYPEIDCONTAINER' VARCHAR2 (30 BYTE) NOT NULL

    )

    INSERT INTO Betinfo (Currentpress, typeidcontainer) VALUES ('A24G', 'PMC');

    INSERT INTO Betinfo (Currentpress, typeidcontainer) VALUES ('A24D', 'Pensky-MARTENS');

    INSERT INTO Betinfo (Currentpress, typeidcontainer) VALUES ("A25D", "CMP");

    INSERT INTO Betinfo (Currentpress, typeidcontainer) VALUES ('A25G', 'PMC');

    INSERT INTO Betinfo (Currentpress, typeidcontainer) VALUES ('A26D', 'PMC');

    INSERT INTO Betinfo (Currentpress, typeidcontainer) VALUES ('A26G', 'PMC');

    INSERT INTO Betinfo (Currentpress, typeidcontainer) VALUES ("A32G", "V-BFC3");

    INSERT INTO Betinfo (Currentpress, typeidcontainer) VALUES ('A32D', "V-BFC2");

    CREATE TABLE 'BETODI '. "" BETMASTER ".

    (

    ACTIVATE THE "CUREPRESS" TANK (5 BYTES) NOT NULL,

    ACTIVATE THE "TYPE" VARCHAR2 (5 BYTE) NOT NULL,

    NUMBER (5.0) "LASTPCIRIM".

    )

    INSERT INTO BetMaster (Curepress, type, lastpcirim) VALUES ('A24', '45 M 8', 15);

    INSERT INTO BetMaster (Curepress, type, lastpcirim) VALUES ('A25', 42 16', 15);

    INSERT INTO BetMaster (Curepress, type, lastpcirim) VALUES ("A26", 16' 45, 15);

    INSERT INTO BetMaster (Curepress, type, lastpcirim) VALUES ("A27", '45 M 34', 16);

    INSERT INTO BetMaster (Curepress, type, lastpcirim) VALUES ('A28', '45 M 34', 16);

    INSERT INTO BetMaster (Curepress, type, lastpcirim) VALUES ('A29', '45 M 34', 16);

    INSERT INTO BetMaster (Curepress, type, lastpcirim) VALUES ('A30', '45MCH', 15);

    INSERT INTO BetMaster (Curepress, type, lastpcirim) VALUES ("A31", "45MCH", 16);

    INSERT INTO BetMaster (Curepress, type, lastpcirim) VALUES ('A32', '45MCH', 16);

    INSERT INTO BetMaster (Curepress, type, lastpcirim) VALUES ('A33', '45MCH', 16);

    INSERT INTO BetMaster (Curepress, type, lastpcirim) VALUES ("A34", "45MCH", 16);

    These two tables have left join as

    BETMASTER. CUREPRESS = substr (BETINFO. CURRENTPRESS, 1, 3)

    now I want to have the data in the two tables with fields Curepress, Lastpcirim, typeidcontainer.

    Also something like

    Make a group of typeidcontainer if this value is greater than 1 by press separated the values of semicolon (;)

    So, for example above, we should be given as

    A24 PMC 15; PENSKY-MARTENS

    A25 15 PMC

    A26 15 PMC

    A27 16 (NULL)

    A28 16 (NULL)

    A30 15 (NULL)

    A31 16 (NULL)

    A32 16 BFC2-V; V BFC3

    A33 16 (NULL)

    A34 16 (NULL)

    How could do?

    My current request is as

    Select distinct Curepress, lastpcirim, typeidcontainer

    BETMASTER STD left join INF BETINFO

    on the trim (STD. CUREPRESS) = substr (trim (INF. CURRENTPRESS), 1, 3)

    but I am unable to get the values separated by commas.

    Any help would be appreciated.

    Thank you

    Mahesh.

    Hi, Mahesh,

    If you want to only 1 row of output for each distinct combination of currentpress and lastpcirim?  This sounds like a job for GROUP BY.

    And you want the row to contain a list of all different typidcontainers-delimited?  This sounds like a job for the aggregate LISTAGG function.

    WITH joined_data AS

    (

    SELECT DISTINCT

    MST.curepress, mst.lastpcirim, inf.typeidcontainer

    OF betmaster STD

    LEFT JOIN betinfo ON TRIM (mst.curepress) inf = SUBSTR (TRIM (inf.currentpress)

    1

    3

    )

    )

    SELECT curepress, lastpcirim

    LISTAGG (typeidcontainer, ',')

    THE Group (ORDER BY typeidcontainer) AS container_list

    OF joined_data

    Curepress GROUP, lastpcirim

    ;

    Unfortunately, you can't say LISTAGG (DISTINCT ...), so you should always get the separate containers how you already are.  (Note that the subquery is just what you posted).

    Thanks for posting the CREATE TABLE and INSERT statements; It is very useful.  Don't forget to tell what version of Oracle you are using.  LISTAGG was new in Oracle 11.2.

    Why not add CHECK constraints (and perhaps triggers) to your tables, so that curepress and currentpress are not stored with the head or trailing spaces?  Then you wouldn't need to use the PAD in queries like this, and your code would be simpler and more effective.

  • Join WITH NULL

    I have table1 and table2.what is the number of lines if I join table1 and table2 col1-based. I told 2 rows. Interview then asked write a query if you want that NULL, NULL in release and I don't know how to do this since Null will not match


    TABLE1:

    COL1, COL2

    1, HAS

    2, B

    NULL, NULL

    TABLE2:

    COL1, COL2

    1 C,

    2, D

    NULL, NULL

    Don't know what the interviewer was looking for

    SQL> with t1
      2  as
      3  (
      4  select 1 id, 'A' name from dual union all
      5  select 2 id, 'B' name from dual union all
      6  select null id, null name from dual
      7  ),
      8  t2
      9  as
     10  (
     11  select 1 id, 'C' name from dual union all
     12  select 2 id, 'D' name from dual union all
     13  select null id, null name from dual
     14  )
     15  select *
     16    from t1
     17    join t2
     18      on nvl(t1.id, -1) = nvl(t2.id, -1);
    
            ID NAME               ID NAME
    ---------- ---------- ---------- ----------
             1 A                   1 C
             2 B                   2 D
    NULL       NULL       NULL       NULL
    
    SQL> with t1
      2  as
      3  (
      4  select 1 id, 'A' name from dual union all
      5  select 2 id, 'B' name from dual union all
      6  select null id, null name from dual
      7  ),
      8  t2
      9  as
     10  (
     11  select 1 id, 'C' name from dual union all
     12  select 2 id, 'D' name from dual union all
     13  select null id, null name from dual
     14  )
     15  select *
     16    from t1
     17    left join t2
     18      on t1.id = t2.id;
    
            ID NAME               ID NAME
    ---------- ---------- ---------- ----------
             1 A                   1 C
             2 B                   2 D
    NULL       NULL       NULL       NULL
    
  • LEFT JOIN DUPLICATION PROBLEM

    Hello

    I'm having a problem with the left join query, when I join table a two table based on column task1 I get duplicate in table1.task1, table1.price.

    Table1. Task1Table1. Pricetable2. Task1table2. Resourcetable2. Price
    001100001A50
    001100001B250

    How can I make a request to get a result as below.

    Table1. Task1Table1. Pricetable2.Task2table2. Resourcetable2. Price
    001100001A50
    001B250

    Thank you.

    Note that your query uses an inner join. Your original question mentioned a join left, generally interpreted as meaning a left OUTER join.

    Anyway, according to Frank, you can use the BREAK command in SQL * Plus for the goal sought through formatting. You can also use an analytical function as Roger suggests. I think ROW_NUMBER() might do the trick, but we must be clear about the criteria for partitioning and ordering the results, for example

    WITH table1 AS (
      SELECT '001' AS task1
           , 100 AS price
      FROM   dual
    ), table2 AS (
      SELECT '001' AS task1
           , 'A' AS resources
           , 50 AS price
      FROM   dual
      UNION ALL
      SELECT '001' AS task1
           , 'B' AS resources
           , 250 AS price
      FROM   dual
    )
    SELECT DECODE(ROW_NUMBER() OVER (PARTITION BY t1.task1, t1.price ORDER BY t2.resources, t2.price),1,t1.task1) AS task1_alt
         , DECODE(ROW_NUMBER() OVER (PARTITION BY t1.task1, t1.price ORDER BY t2.resources, t2.price),1,t1.price) AS price_alt
         , t2.task1 AS task_with_resource
         , t2.resources
         , t2.price
    FROM   table1 t1
    INNER JOIN table2 t2
    ON     t1.task1 = t2.task1
    ORDER BY t1.task1, t1.price, t2.resources, t2.price;
    
  • Interesting behavior of left join

    We will create 3 tables as follows:


    CREATE TABLE "A1" ()"A1_ID" NUMBER ENABLE NON NULL,CONSTRAINT "A1_PK" SELECT the PRIMARY KEY ('A1_ID') );

    CREATE TABLE "A2" ()"A2_ID" NUMBER ENABLE NON NULL,CONSTRAINT "A2_PK" SELECT the PRIMARY KEY ('A2_ID'));

    CREATE TABLE "A12" ()'A12_ID' ENABLE NUMBER NOT NULL,'A1_ID' ENABLE NUMBER NOT NULL,'A2_ID' ENABLE NUMBER NOT NULL,"A12_PK" PRIMARY KEY ('A12_ID'), CONSTRAINTREFERENCES of FOREIGN ("A1_ID") of CONSTRAINT "A12_A1_FK1" "BUTUNLESIK" KEY "" A1 "("A1_ID") ENABLE,KEY REFERENCES FOREIGN ("A2_ID") of CONSTRAINT 'A12_A2_FK1' 'BUTUNLESIK '. ("" A2 "("A2_ID") ALLOW);

    We insert the values as follows:

    Insert into A1 values (1);

    Insert into A1 values (2);

    Insert into A1 values (3);

    Insert 4 A1;

    Insert into A1 values (5);

    Insert into A1 values (6);

    Insert into A2 values (1);

    insert into values A12 (1,1,1);

    Tables a1 and A2 are just simple tables with primary keys and A12 table contains many-to-many relationship between them.

    When I run the query below,

    SELECT * A1 A1 A12 A12 LEFT JOIN ON a1.a1_id = a12.a1_id A2 LEFT JOIN A2 ON a2.a2_id = a12.a2_id WHERE a2.a2_id IS NULL;

    I get the following results, as I predicted:

    A1_ID A12_ID A1_ID A2_ID A2_ID

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

    6

    5

    4

    3

    2

    However when I run the second query below (where I select only the a1 id column instead of "*")

    SELECT a1.a1_id A1 A1 A12 A12 LEFT JOIN ON a1.a1_id = a12.a1_id A2 LEFT JOIN A2 ON a2.a2_id = a12.a2_id WHERE a2.a2_id IS NULL;


    I get nothing, no lines have been selected. When I look at the plan of the second query I see a predicate to filter such as "'NULL IS NOT NULL". " I guess that this does not return results. Is this a bug, or y at - it a satisfactory explanation for this behavior?

    Step 1 - check the execution plans.

    At first glance, this looks like a variant of https://forums.oracle.com/thread/2594321

    Concerning

    Jonathan Lewis

  • Left join between two tables using two different conditions

    I have following three tables with their data, as shown below.

    CREATE TABLE TIREMASTERPROCESS_TEMP
    (
    PRODUCTIONCODE TANK (12 BYTES),
    FIELDNAME CHAR (12 BYTES),
    DATACHR VARCHAR2 (60 BYTE),
    REVISIONNO TANK (3 BYTES),
    DATANUM NUMBER (9.4)
    )
    Whether the table c. and its sample data are like

    FIELDNAME DATACHR REVISIONNO DATANUM PRODUCTIONCODE
    AB No. Nch 1 100 0
    AB No. Nch 1 108 0
    AB No.-of-Nch 1 1 0
    Ass42 teased dishes 1 0
    Ass42 BTDrumNo1 BTD-051 1 0
    AB53 BTDrumNo1 BTD-051 104 0


    CREATE TABLE materialcode
    (
    UPPERMATERIALCODE CHAR (20),
    PROCESSNO TANK (3),
    PROCESSADOPTDATE TANK (9)

    )
    Whether the table b. and its sample data are like

    UPPERMATERIALCODE PROCESSNO PROCESSADOPTDATE
    Ass42 1 20120717
    AB53 108 20121121
    111 20111104 AS05
    104 20120928 AS30


    CREATE TABLE BUILDINGSCHEDULEMASTER
    (
    BUILDINGSIZE TANK (5 BYTES),
    GTCODE FLOAT (4 BYTES),
    TIREPERCART NUMBER (3.0).
    BUILDINGLOT NUMBER (3.0)
    )
    Whether table and its sample data are like

    BUILDINGSIZE GTCODE TIREPERCART BUILDINGLOT
    AB42A 4 12 ass42
    AB53A 4 88 AB53
    AS30A AS30 4 80
    BF03A 1 90 BF03


    Now, I need to get some data in these fields by using the suite of mappings.

    « PR_ » || Trim (a.BUILDINGSIZE) | ' / MPL2' Processid,--PRIMARY KEY
    TO_DATE (substr (NVL(b.PROCESSADOPTDATE,'19800101'), 7, 2) |) » /'|| SUBSTR (NVL(b.PROCESSADOPTDATE,'19800101'), 5, 2) | » /'|| SUBSTR (NVL(b.PROCESSADOPTDATE,'19800101'), 1, 4). (' 01:00:00 ',' dd-mm-yyyy hh24:mi:ss') starteff, to_date (SUBSTR (NVL(b.PROCESSADOPTDATE,'19800101'), 7, 2) |) » /'|| SUBSTR (NVL(b.PROCESSADOPTDATE,'19800101'), 5, 2) | » /'|| SUBSTR (NVL(b.PROCESSADOPTDATE,'19800101'), 1, 4). (' 01:00:00 ',' dd-mm-yyyy hh24:mi:ss') startDate.
    b.PROCESSNO revisioncodeid,
    a.BUILDINGLOT tirepercart ,
    CASE WHEN c.FIELDNAME = 'BTDrumNo1' then c.DATACHR end drumtype1.
    BOX WHEN (trim (C.DATACHR) = '1' and trim (C.FIELDNAME) = "No. Nch") and THEN click 'YES '.
    ANOTHER 'NO '.
    END may-BUG,
    case
    When c.FIELDNAME = 'Wavy'
    AND c.DATACHR = 'Use' THEN on 'YES '.
    When c.FIELDNAME = 'Wavy'
    AND c.DATACHR <>'Use' THEN 'NO '.
    fine wavy


    Now for the tables A and B I have the simple join as condition

    a.GTCODE = b.UPPERMATERIALCODE

    But I have to use two different left join conditions to join the table B and C to calculate the RESP fields according to the condition.
    Now, I have to use

    (trim (b.UPPERMATERIALCODE)). » -'|| Trim (b.PROCESSNO) = Trim (c.PRODUCTIONCODE) | » -'|| Trim (c.REVISIONNO)

    condition to get the data for the WAVY and DRUMTYPE1 fields.

    But at the same time, I have to use

    substr (Trim (b.UPPERMATERIALCODE), 1, 2). » -'|| Trim (b.PROCESSNO) = Trim (c.PRODUCTIONCODE) | » -'|| Trim (c.REVISIONNO)

    conition to derive the CHAFER field.

    And for this reason I am come so many duplicates and do not correct results for JUNEBUG, WAVY, DRUMTYPE1, and STARTDATE field.

    I need some advice as how can I do so that I get the correct results without duplicates for the PRIMARY KEY.

    Thank you

    Mahesh

    It would have been easier to answer if you gave us your example query that gives incorrect results - which both show us what you are doing and give us a starting point.
    Insert instructions for data, rather than only the data would have helped too, making it more quick to test this point.
    You do not show what you have done with your two outer join criteria, but I think you need to list TIREMASTERPROCESS_TEMP in your query twice, with alias names. Here's what I did:

    select a.BUILDINGSIZE, a.GTCODE, b.PROCESSNO ,  c1.FIELDNAME, c1.DATACHR, C2.FIELDNAME, C2.DATACHR
    , CASE WHEN c1.FIELDNAME='BTDrumNo1' then c1.DATACHR end drumtype1
    , CASE WHEN (trim(c2.DATACHR) = '1' and trim(c2.FIELDNAME) = 'No-of-Nch') THEN 'YES' ELSE 'NO' END CHAFER
    , case when c1.FIELDNAME='Wavy' AND c1.DATACHR='Use' THEN 'YES'
           when c1.FIELDNAME='Wavy' then 'NO' else null end wavy
    from BUILDINGSCHEDULEMASTER        A
    join materialcode b on a.GTCODE=b.UPPERMATERIALCODE
    left outer join TIREMASTERPROCESS_TEMP c1
       ON trim(b.UPPERMATERIALCODE)||'-'||trim(b.PROCESSNO) = trim(c1.PRODUCTIONCODE)||'-'||trim(c1.REVISIONNO)
    left outer join TIREMASTERPROCESS_TEMP c2
       ON substr(trim(b.UPPERMATERIALCODE),1,2)||'-'||trim(b.PROCESSNO) = trim(c2.PRODUCTIONCODE)||'-'||trim(c2.REVISIONNO)
    

    C1 is an alias for the TIREMASTERPROCESS_TEMP line which is necessary for drumtype1 and wavy, c2 is an alias for the TIREMASTERPROCESS_TEMP line required for JuneBug. There was some minor errors in your calculations of field I tried to correct.

    The results are:

    BUILD GTCO PRO FIELDNAME    DATACHR    FIELDNAME    DATACHR    DRUMTYPE1  CHA WAV
    ----- ---- --- ------------ ---------- ------------ ---------- ---------- --- ---
    AB53A AB53 108                         No-of-Nch    1                     YES
    AB42A AB42 1   BTDrumNo1    BTD-051    No-of-Nch    1          BTD-051    YES
    AB42A AB42 1   Wavy         NotUse     No-of-Nch    1                     YES NO
    AS30A AS30 104                                                            NO
    

    Hope this helps,
    David

  • Inner join with an asymmetric column: plan not optimized SQL

    Hello

    I think that it is a FAQ, but I was unable to get a useful answer by Googling.

    Oracle version is 11.2.0 on Sparc64.

    Consider the following code:
    drop table x;
    PROMPT
    PROMPT Populate x with some users. Note the iduser PK
    PROMPT
    
    create table x as
    select 1 iduser, 'PUBLIC' owner from dual
    union
    select 2 iduser, 'SYSTEM' owner from dual
    union
    select 3 iduser, 'XDB' owner from dual
    union
    select 4 iduser, 'APPQOSSYS' owner from dual
    union
    select 5 iduser, 'SYS' owner from dual
    union
    select 6 iduser, 'OUTLN' owner from dual
    union
    select 7 iduser, 'DBSNMP' owner from dual
    /
    
    alter table x add constraint pk_x primary key(iduser);
    
    
    PROMPT
    PROMPT Create a table y from all_objects, but using the previous iduser 
    PROMPT as foreign key (owner column is not needed). Note the index
    PROMPT on column iduser
    PROMPT
    
    drop table y
    /
    create table y as
    select x.iduser, all_objects.*
    from all_objects, x
    where x.owner = all_objects.owner
    and x.owner in  ( 'PUBLIC', 'SYSTEM', 'XDB', 'APPQOSSYS',
        'SYS', 'OUTLN', 'DBSNMP')
    /
    alter table y drop column owner;
    alter table y add constraint y_fk foreign key(iduser) references x;
    create index idx_y on y(iduser);
    
    PROMPT
    PROMPT Take some stats. X stats are irrelevant, I think
    PROMPT
    exec dbms_stats.gather_table_stats( -
        USER, -
        'Y', -
        estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, -
        degree => DBMS_STATS.DEFAULT_DEGREE, -
        cascade => true, -
        method_opt => 'FOR COLUMNS IDUSER SIZE AUTO', -
        granularity => 'ALL' -
    )
    exec dbms_stats.gather_table_stats( -
        USER, -
        'X', -
        estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, -
        degree => DBMS_STATS.DEFAULT_DEGREE, -
        cascade => true, -
        method_opt => 'FOR COLUMNS IDUSER SIZE AUTO', -
        granularity => 'ALL' -
    )
    
    set autotrace trace exp
    
    PROMPT
    PROMPT APPQOSSYS has only 5 objects (well, your output may vary, but it should by
    PROMPT very similar), but the following query ignore the index and do a full scan on Y
    PROMPT
    select x.*, y.*
    from x, y
    where x.owner = 'APPQOSSYS'
    and y.iduser = x.iduser
    /
    
    PROMPT
    PROMPT Virtually, equivalent to the previous one. But the explain plan is very different
    PROMPT and the index is used
    PROMPT
    
    select y.*
    from x, y
    where x.owner = 'APPQOSSYS'
    and y.iduser = 4
    /
    
    set autotrace off
    The result is:
    ............................ [snip] .........................
    
    ( EXPLAIN PLAN OF FIRST QUERY)
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1702571549
    
    ---------------------------------------------------------------------------
    | Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |   559 | 58136 |   142   (1)| 02:23:19 |
    |*  1 |  HASH JOIN         |      |   559 | 58136 |   142   (1)| 02:23:19 |
    |*  2 |   TABLE ACCESS FULL| X    |     1 |     9 |     2   (0)| 00:02:02 |
    |   3 |   TABLE ACCESS FULL| Y    | 55883 |  5184K|   139   (0)| 02:20:47 |
    ---------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - access("Y"."IDUSER"="X"."IDUSER")
       2 - filter("X"."OWNER"='APPQOSSYS')
    
    
    
    ( EXPLAIN PLAN OF SECOND QUERY)
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 2241001346
    
    -------------------------------------------------------------------------------------
    | Id  | Operation                   | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    -------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |       |    10 |   950 |     2   (0)| 00:02:02 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| Y     |    10 |   950 |     2   (0)| 00:02:02 |
    |*  2 |   INDEX RANGE SCAN          | IDX_Y |    10 |       |     1   (0)| 00:01:01 |
    -------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("Y"."IDUSER"=4)
    Well, the question is very simple: is it possible to get the first query to take the index and to avoid complete analysis? With no clues, of course.

    All of your advice and comments will be welcome. Thanks in advance.

    Best regards

    jjuanino wrote:

    Well, the question is very simple: is it possible to get the first query to take the index and to avoid complete analysis? With no clues, of course.

    All of your advice and comments will be welcome. Thanks in advance.

    This is a limit known optimizer - no realistic solution.

    The optimizer can recognize with the help of a histogram iduser on table column is very unevenly distributed, but there is not a generic strategy to recognize what owner on the table of X corresponds to what iduser on the table of Y.

    An approach that can help - even if I do not remember seeing documented is to rewrite the query with a subquery and use the / * + precompute_subquery * / tip.
    I have not tried with your data, but something like:

    select * from y
    where iduser in (
        select /*+ precompute_subquery */ x.iduser
        from x
        where owner = 'APPQSYS'
        )
    ;
    
    Regards
    Jonathan Lewis
    
    P.S.  Found a reference note by Tanel Poder: http://blog.tanelpoder.com/2009/01/23/multipart-cursor-subexecution-and-precompute_subquery-hint/
    
  • Seen the lock of brain on Left Join

    Always on Oracle 11.2.0.1.0

    Examples of data
    CREATE TABLE theEmails (
    RID NUMBER(10) PRIMARY KEY,
    employee NUMBER(6),
    emailType VARCHAR2(4),
    emailAddress VARCHAR2(50),
    emailActive number(1)
    )
    ;
    INSERT INTO theEmails VALUES(778437,231509,'OTHR','[email protected]',0);
    INSERT INTO theEmails VALUES(847168,231509,'WRK1','[email protected]',0);
    INSERT INTO theEmails VALUES(784690,231509,'OTHR','[email protected]',1);
    INSERT INTO theEmails VALUES(1459884,239868,'OTHR','[email protected]',0);
    INSERT INTO theEmails VALUES(1485781,239868,'OTHR','[email protected]',1);
    INSERT INTO theEmails VALUES(1485782,239868,'WRK1','[email protected]',0);
    INSERT INTO theEmails VALUES(1501028,231509,'WRK1','[email protected]',1);
    INSERT INTO theEmails VALUES(1492288,239868,'WRK1','[email protected]',1);
    INSERT INTO theEmails VALUES(1456785,239865,'OTHR','[email protected]',0);
    INSERT INTO theEmails VALUES(1489166,239865,'WRK1','[email protected]',0);
    INSERT INTO theEmails VALUES(1482668,239865,'WRK1','[email protected]',0);
    INSERT INTO theEmails VALUES(1482667,239865,'OTHR','[email protected]',1);
    
    
    
    CREATE TABLE thePeople (
    employee NUMBER(6),
    recordNum NUMBER(2),
    lastName VARCHAR2(20),
    firstName VARCHAR2(20)
    )
    ;
    
    INSERT INTO thePeople VALUES(231509,0,'P','Michelle');
    INSERT INTO thePeople VALUES(239868,0,'K','Dan');
    INSERT INTO thePeople VALUES(239865,0,'T','Mary');
    So, here is my SQL that does not work well:
    SELECT p.employee, p.recordNum, p.lastName, p.firstName, e.emailaddress, e.emailactive, e.emailtype
    FROM thePeople p LEFT JOIN theemails e ON p.employee = e.employee
    WHERE (e.emailactive = 1)
          AND
          (e.emailtype = 'WRK1')
          AND
          (e.emailaddress LIKE '%school.edu')
    ;
    AND this:
    SELECT p.employee, p.recordNum, p.lastName, p.firstName, e.emailaddress, e.emailactive, e.emailtype
    FROM thePeople p LEFT JOIN theemails e ON p.employee = e.employee
    WHERE (e.emailactive = 1 OR e.emailactive IS NULL)
          AND
          (e.emailtype = 'WRK1' OR e.emailtype IS NULL)
          AND
          (e.emailaddress LIKE '%school.edu' OR e.emailaddress IS NULL)
    Both give me this:

    employee | record | lastName. firstName. emailAddress. emailActive | emailType
    231509 | 0 | P     | Michelle | [email protected] | 1. WRK1


    But what I need is the following:
    employee | record | lastName. firstName. emailAddress. emailActive | emailType
    239868 | 0 | K     | Dan |      |     |
    231509 | 0 | P     | Michelle | [email protected] | 1. WRK1
    239865 | 0 | T     | Mary |          |


    Email from Dan is not included, because his "wrk1" email does not stop it school.edu
    E-mail Mary is not included, because his 'wrk1' email is not active.
    However, I need to come back with their numbers of name registration and employee.


    Once it works, I'll add employee = number in the WHERE clause, because I only need to find a person both for the actual production.

    What I am doing wrong?

    Thank you!

    Michelle

    Hello

    WHERE is the filtering actually record the selection.

    In your case, you might want to include in your LEFT OUTER JOIN ON conditions:

    SELECT p.employee, p.recordnum, p.lastname, p.firstname
         , e.emailaddress, e.emailactive, e.emailtype
      FROM    thepeople p
           LEFT JOIN
              theemails e
           ON     p.employee = e.employee
              AND e.emailactive = 1
              AND e.emailtype = 'WRK1'
              AND e.emailaddress LIKE '%school.edu';
    

    If you put them in your JOIN conditions actually join Chronogram of table theemails that adapt to the conditions of membership.
    As you use LEFT [OUTER] JOIN unmatched chronogram thepeople table will be displayed even when the theemail table column appears with a NULL value in the output files

    I hope that I was able to unlock your brain. :-)

    Kind regards.
    Al

    Published by: Alberto Faenza on 25 October 2012 16:58
    Additional note added

  • strange result of Left Join 11 GR 2.

    It is a strange result of Left Join
    Why the result is 0 record?
    select * from v$version;
    
    BANNER
    -------------------------------------------------------
    Oracle Database 11g Release 11.2.0.1.0 - Production
    PL/SQL Release 11.2.0.1.0 - Production
    CORE    11.2.0.1.0      Production
    TNS for 32-bit Windows: Version 11.2.0.1.0 - Production
    NLSRTL Version 11.2.0.1.0 - Production
    Select * From
    (Select 1 aaa From DUAL) A
    LEFT JOIN
    (Select 2 bbb From DUAL Where '1' IN ('2','3')) B
    ON A.aaa = B.bbb;
    
    no rows selected
    Old Left Join syntax does not work, too :-(
    Select * From
    (Select 1 aaa From DUAL) A,
    (Select 2 bbb From DUAL Where '1' IN ('2','3')) B
    where A.aaa = B.bbb(+);
    
    no rows selected

    Aketi Jyuuzou wrote:
    It is a strange result of Left Join
    Why the result is 0 record?

    I guess that the rewrite of the query with the optimizer is the origin of the problem.
    Say the 10053 trace? I don't have access to the database 11 GR 2 now to test.
    You can see if the advice of line NO_REWRITE or NO_QUERY_TRANSFORMATION gives the desired result.

Maybe you are looking for