Merge Query Question

Ok, I have a Table TEST_ACCOUNTS that has all new customer information of new applicants for credit cards. Because of a Bank rules, customers are not assigned
a customer_id number right away, takes about a month, so in this table I will have some CUST_SKEYS that are [0] and some that have account numbers.
I pick off all the [0] from this Table above and find out which ones got an account and those go into a Table LATEST_SKEYS but not all of them will update, so
there will still be some [0]'s.
Anyways, so now I would like to MERGE the accounts that were found back to the master Table, which is TEST_ACCOUNTS using the query below, the query does
work, but all cust_skeys that used to be 0 were turned to null, and I would prefer for them to stay 0. I know that I can use NVL and NVL2 to turn a null value to whatever I want,
but I only have experience using that when I select columns form existing tables, am not sure how to do this with a MERGE, something that I want to learn more about.
It isn't really creating a headache for me, but I would like to keep things consistent and keep the 0, 0's and not NULL.
Another columns that rides along with the row information is app_num, which is a unique number that is assigned to an application for a credit card so I am doing the matching
on that and then I update the cust_skeys.
Hopefully this makes sense. Help appreciated.
MERGE INTO TEST_ACCOUNTS t1
USING (Select * from LATEST_SKEYS) t2
ON (t1.application_num = t2.application_num)
WHEN MATCHED THEN UPDATE
SET t1.cust_skey = t2.customer_skey;

user621335 wrote:
... the query does
work, but all cust_skeys that used to be 0 were turned to null, and I would prefer for them to stay 0.
MERGE INTO TEST_ACCOUNTS t1
USING (Select * from LATEST_SKEYS) t2
ON (t1.application_num = t2.application_num)
WHEN MATCHED THEN UPDATE
SET t1.cust_skey = t2.customer_skey;You probably want to limit the records returned by t2 to just those whose customer_skey values are not null:
MERGE INTO TEST_ACCOUNTS t1
USING (Select * from LATEST_SKEYS where customer_skey is not null) t2
ON (t1.application_num = t2.application_num)
WHEN MATCHED THEN UPDATE
SET t1.cust_skey = t2.customer_skey;

Similar Messages

  • Need Help In Merge query

    Hi ,
    i m using merge query .
    below is my query .
    MERGE INTO tbltmonthlysales A
    USING
    (select DISTINCT 'JAN-2011' MON_YYYY,distributorname DISTRIBUTORNAME From SYN_VWABS) B
    ON (a.distributorname = B.distributorname)
    WHEN NOT MATCHED THEN
    INSERT (A.MON_YYYY,A.distributorname) VALUES (B.MON_YYYY,B.DISTRIBUTORNAME);
    ------Now Firing this query ---
    1)
    SQL> MERGE INTO tbltmonthlysales A
    2 USING
    3 (select DISTINCT 'JAN-2011' MON_YYYY,distributorname DISTRIBUTORNAME From SYN_VWABS) B
    4 ON (a.distributorname = B.distributorname)
    5 WHEN NOT MATCHED THEN
    6 INSERT (A.MON_YYYY,A.distributorname) VALUES (B.MON_YYYY,B.DISTRIBUTORNAME);
    INSERT (A.MON_YYYY,A.distributorname) VALUES (B.MON_YYYY,B.DISTRIBUTORNAME)
    ERROR at line 6:
    ORA-00904: "B"."DISTRIBUTORNAME": invalid identifier
    now i m createing one table
    create table test2 as select * from SYN_VWABS
    2)
    SQL> MERGE INTO tbltmonthlysales A
    2 USING
    3 (select DISTINCT 'JAN-2011' MON_YYYY,distributorname DISTRIBUTORNAME From test2) B
    4 ON (a.distributorname = B.distributorname)
    5 WHEN NOT MATCHED THEN
    6 INSERT (A.MON_YYYY,A.distributorname) VALUES (B.MON_YYYY,B.DISTRIBUTORNAME);
    INSERT (A.MON_YYYY,A.distributorname) VALUES (B.MON_YYYY,B.DISTRIBUTORNAME)
    71 rows merged.
    My question is why my 1) query is not executing?

    thanks your efforts are apriciated but its not working
    see i have created view as per ur suggestion,
    create or replace view vwabc as
    SELECT x.accountnumber accountnumber,
    distributorname distributorname,
    staffname staffname,
    resellerno resellerno,
    resellername resellername, resellercreatedate resellercreatedate, customerno customerno, custmername custmername,
    customeractivationdate customeractivationdate, childaccountnumber childaccountnumber, childaccountname childaccountname,
    childactivationdate childactivationdate, resellerstaff resellerstaff
    --x.accountstaffid Disaccountstaffid,
    --y.accountstaffid resaccountstaffid
    FROM (SELECT Y.RELATIONACCOUNTNUMBER accountnumber, x.NAME distributorname, staffname,
    y.accountnumber resellerno, y.accountid resaccountid,
    x.accountstaffid
    FROM ((SELECT a.accountid, b.accountstaffid, a.NAME,
    b.NAME staffname, a.accountnumber
    FROM tblmaccount a, tblmaccountstaff b
    WHERE a.accounttypeid = 'ACT04' AND a.accountid = b.owneraccountid(+))
    UNION ALL
    (SELECT a.accountid, NULL, a.NAME, NULL, a.accountnumber
    FROM tblmaccount a
    WHERE a.accounttypeid = 'ACT04'
    AND EXISTS (SELECT 1
    FROM tblmaccountstaff c
    WHERE c.owneraccountid = a.accountid))) x,
    tblmaccountaccountrel y
    WHERE NVL (x.accountstaffid, '-') = NVL (y.accountstaffid(+), '-')
    AND x.accountid = y.relationaccountid(+)
    --and x.accountid = 'ACC000537173'
    ) x,
    (SELECT x.accountnumber, x.NAME resellername, resellerstaff,
    x.accountstaffid, y.accountnumber customerno,
    ta.NAME custmername, ta.accountid,
    ta.activationdate customeractivationdate,
    y.relationaccountid, cust.accountnumber childaccountnumber,
    cust.NAME childaccountname,
    TRUNC (cust.activationdate) childactivationdate,
    x.resellercreatedate
    FROM ((SELECT a.accountid, b.accountstaffid, a.NAME,
    b.NAME resellerstaff, a.accountnumber,
    TRUNC (a.createdate) resellercreatedate
    FROM tblmaccount a, tblmaccountstaff b
    WHERE a.accounttypeid = 'ACT03' AND a.accountid = b.owneraccountid(+))
    UNION ALL
    (SELECT a.accountid, NULL, a.NAME, NULL, a.accountnumber,
    TRUNC (a.createdate) resellercreatedate
    FROM tblmaccount a
    WHERE a.accounttypeid = 'ACT03'
    AND EXISTS (SELECT 1
    FROM tblmaccountstaff c
    WHERE c.owneraccountid = a.accountid))) x,
    tblmaccountaccountrel y,
    tblmaccount ta,
    tblmaccount cust
    WHERE NVL (x.accountstaffid, '-') = NVL (y.accountstaffid, '-')
    AND x.accountid = y.relationaccountid(+)
    AND y.accountid = ta.accountid(+)
    AND ta.accountnumber = cust.parentaccountnumber
    --and x.accountid = 'ACC000537856'
    ) y
    WHERE x.resaccountid = y.relationaccountid(+)
    Now firing Merge,
    SQL> MERGE INTO tbltmonthlysales A
    2 USING
    3 (select DISTINCT MON_YYYY ,distributorname From vwabc) B
    4 ON (a.distributorname = B.distributorname)
    5 WHEN NOT MATCHED THEN
    6 INSERT (A.MON_YYYY,A.distributorname) VALUES (B.MON_YYYY,B.DISTRIBUTORNAME);
    (select DISTINCT MON_YYYY ,distributorname From vwabc) B
    ERROR at line 3:
    ORA-00904: "MON_YYYY": invalid identifier
    still error :(

  • Executing a merge query for a collection

    Hello All,
    I am trying to use a merge query to find common and uncommon ids between a table and a list I pass to my pl-sql proc. I am not sure if I am doing the right thing, please guide me...
    Here is my code...
    Procedure process_content(i_eidlist IN ocs_eid_list_t, i_id IN number, o_new_email_list OUT ocs_eid_list_t) AS
    lv_last_processed_row_id number;
    lv_common_email_list ocs_eid_list_t;
    lv_internet_id varchar2;
    Begin
    lv_last_processed_row_id := 0;
    MERGE INTO table c
    USING TABLE(i_eidlist)a
    ON (c.eid in a)
    --WHEN MATCHED THEN UPDATE SET c.row_id = job_no_seq.NEXTVAL,c.copy_count=1 returning row_id bulk collect into lv_row_id_list;
    WHEN MATCHED THEN SELECT c.eid bulk collect into lv_common_email_list returning row_id bulk collect into lv_row_id_list
    WHEN NOT MATCHED THEN SELECT c.eid bulk collect into o_new_email_list;
    I am assuming that the merge query is going to iterate over the i_eidlist, and find me the common and uncommon elements. However, I get an error saying the sql block is ignored.
    Thanks
    Abhishek
    글 수정: A.J.

    I do not think it is possible in one pass. The best I could come up with:
    DECLARE
        COMMON_LIST NAME_LIST;
        UNCOMMON_LIST NAME_LIST;
        EMPLOYEE_LIST NAME_LIST;
        CHECK_LIST NAME_LIST := NAME_LIST('KING','QUEEN');
    BEGIN
        SELECT  ENAME
          BULK COLLECT INTO EMPLOYEE_LIST
          FROM  EMP;
        COMMON_LIST := EMPLOYEE_LIST MULTISET INTERSECT CHECK_LIST;
        UNCOMMON_LIST := EMPLOYEE_LIST MULTISET EXCEPT CHECK_LIST;
    DBMS_OUTPUT.PUT_LINE('-- COMMON_LIST --');
    FOR i IN 1..COMMON_LIST.COUNT LOOP
      DBMS_OUTPUT.PUT_LINE(COMMON_LIST(i));
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('-- UNCOMMON_LIST --');
    FOR i IN 1..UNCOMMON_LIST.COUNT LOOP
      DBMS_OUTPUT.PUT_LINE(UNCOMMON_LIST(i));
    END LOOP;
    END;
    /Run results showing contents:
    SQL> DECLARE
      2      COMMON_LIST NAME_LIST;
      3      UNCOMMON_LIST NAME_LIST;
      4      EMPLOYEE_LIST NAME_LIST;
      5      CHECK_LIST NAME_LIST := NAME_LIST('KING','QUEEN');
      6  BEGIN
      7      SELECT  ENAME
      8        BULK COLLECT INTO EMPLOYEE_LIST
      9        FROM  EMP;
    10      COMMON_LIST := EMPLOYEE_LIST MULTISET INTERSECT CHECK_LIST;
    11      UNCOMMON_LIST := EMPLOYEE_LIST MULTISET EXCEPT CHECK_LIST;
    12  DBMS_OUTPUT.PUT_LINE('-- COMMON_LIST --');
    13  FOR i IN 1..COMMON_LIST.COUNT LOOP
    14    DBMS_OUTPUT.PUT_LINE(COMMON_LIST(i));
    15  END LOOP;
    16  DBMS_OUTPUT.PUT_LINE('-- UNCOMMON_LIST --');
    17  FOR i IN 1..UNCOMMON_LIST.COUNT LOOP
    18    DBMS_OUTPUT.PUT_LINE(UNCOMMON_LIST(i));
    19  END LOOP;
    20  END;
    21  /
    -- COMMON_LIST --
    KING
    -- UNCOMMON_LIST --
    SMITH
    ALLEN
    WARD
    JONES
    MARTIN
    BLAKE
    CLARK
    SCOTT
    TURNER
    ADAMS
    JAMES
    FORD
    MILLER
    PL/SQL procedure successfully completed.
    SQL> SY.

  • Error in merge query of the Proc.

    Hi all,
    Below merge query working fine, if I execite independently. I am getting error as "ORA-00900: invalid SQL statement" when i paste this code inside the procedure. However, if I comment the lines written in bold, proc is working fine. Not sure why the comparison not happening even though code and data is correct. If i use like intead of IN then it is working fine.
    Can you please suggest on this?
    MERGE INTO ENTRYPOINTASSETS
    USING
    (SELECT
    LAST_DAY(TRUNC(to_timestamp(oa.reqdate, 'yyyymmddhh24:mi:ss.ff4'))) as activity_month,
    oa.acctnum as acctnum,
    l.lkpvalue as assettype,
    LOWER(trim(oa.disseminationmthd)) as deliverymthd,
    epa.assetid as assetid,
    epa.assetname as assetname,
    count(1) as entrypointcount
    FROM action oa, asset epa, lookupdata l
    WHERE
    oa.assetkey IS NOT NULL
    AND oa.acctnum is not null
    AND trim(oa.assettype) IN ('NL','WS','AL')
    AND l.lkpid = epa.assettypeid
    AND UPPER(trim(oa.disseminationmthd)) IN ('ABC','BCD', 'PODCAST', 'EMAIL','ED', 'WID')
    AND epa.assetkey = oa.assetkey
    AND epa.assetid <> 0
    GROUP BY
    LAST_DAY(TRUNC(to_timestamp(oa.reqdate, 'yyyymmddhh24:mi:ss.ff4'))),
    oa.acctnum,
    l.lkpvalue,
    LOWER(trim(oa.disseminationmthd)),
    epa.assetid,
    epa.assetname
    ) cvd1
    ON
    (ENTRYPOINTASSETS.activity_month = cvd1.activity_month
    AND ENTRYPOINTASSETS.acctnum = cvd1.acctnum
    AND ENTRYPOINTASSETS.assettype = cvd1.assettype
    AND UPPER(ENTRYPOINTASSETS.deliverymthd) = UPPER(cvd1.deliverymthd)
    AND ENTRYPOINTASSETS.assetid = cvd1.assetid)
    WHEN NOT MATCHED THEN
    INSERT (activity_month, acctnum, assettype, deliverymthd, assetid, assetname, entrypointcount)
    VALUES (cvd1.activity_month, cvd1.acctnum, cvd1.assettype, cvd1.deliverymthd, cvd1.assetid, cvd1.assetname, cvd1.entrypointcount)
    WHEN MATCHED THEN
    UPDATE
    SET ENTRYPOINTASSETS.assetname = cvd1.assetname;
    Edited by: Nagaraja Akkivalli on Aug 9, 2011 6:07 PM

    Tried it. No luck. Facing the same problem.
    MERGE INTO SUMMARYTABLE
    USING
    (SELECT
    LAST_DAY(TRUNC(to_timestamp(oa.reqdate, 'yyyymmddhh24:mi:ss.ff4'))) as activity_month,
            oa.acctnum as acctnum,
            l.lkpvalue as assettype,
            LOWER(TRIM(oa.disseminationmthd)) as deliverymthd,
            epa.assetid as assetid,
            epa.assetname as assetname,
            count(1) as entrypointcount
       FROM ods_action oa, ods_asset epa, ods_lookupdata l
      WHERE
         (lv_summm_type_indicator  = c_summaryType_fullLoad
         AND  ( get_date_timestamp(oa.reqdate) BETWEEN :sum_startdate AND :sum_enddate
         AND   oa.uploaddatetime BETWEEN :partitioned_start_date AND :partitioned_end_date
         OR (lv_summm_type_indicator = c_summaryType_incrementLoad
                    AND oa.uploaddatetime BETWEEN :sum_startdate AND :sum_enddate )
        AND oa.assetkey IS NOT NULL
        AND oa.acctnum is not null
        AND UPPER(TRIM(oa.assettype)) IN ('NL','WS','AL')
        AND l.lkpid = epa.assettypeid
        AND UPPER(TRIM(oa.disseminationmthd)) IN ('RSS','PCAST', 'PODCAST', 'EMAIL','ED', 'WID')
        AND epa.assetkey = oa.assetkey
        AND epa.assetid <> 0
      GROUP BY
      LAST_DAY(TRUNC(to_timestamp(oa.reqdate, 'yyyymmddhh24:mi:ss.ff4'))),
               oa.acctnum,
               l.lkpvalue,
               LOWER(TRIM(oa.disseminationmthd)),
               epa.assetid,
               epa.assetname
           ) cvd1
    ON
       (SUMMARYTABLE.activity_month = cvd1.activity_month
        AND SUMMARYTABLE.acctnum = cvd1.acctnum
        AND SUMMARYTABLE.assettype = cvd1.assettype
        AND UPPER(TRIM(SUMMARYTABLE.deliverymthd)) = UPPER(TRIM(cvd1.deliverymthd))
        AND SUMMARYTABLE.assetid = cvd1.assetid)
    WHEN NOT MATCHED THEN
    INSERT (activity_month, acctnum, assettype, deliverymthd, assetid, assetname, entrypointcount)
    VALUES (cvd1.activity_month, cvd1.acctnum, cvd1.assettype, cvd1.deliverymthd, cvd1.assetid, cvd1.assetname, cvd1.entrypointcount)
    WHEN MATCHED THEN
    UPDATE
    SET SUMMARYTABLE.assetname = cvd1.assetname,
        SUMMARYTABLE.entrypointcount =
         CASE WHEN NVL(lv_summm_type_indicator,c_summaryType_incrementLoad) = c_summaryType_fullLoad THEN cvd1.entrypointcount
         ELSE SUMMARYTABLE.entrypointcount + cvd1.entrypointcount END;If I comment any one of the below piece of code present in merge then merge is working fine. If I retain both code then getting error.
    lv_summm_type_indicator is a variable caclualted @ run time to check type of summarization and c_summaryType_incrementLoad is a constant value stored @ the top of the procedure. PLease let me now where I am going wrong.
         (lv_summm_type_indicator  = c_summaryType_fullLoad
         AND  ( get_date_timestamp(oa.reqdate) BETWEEN :sum_startdate AND :sum_enddate
         AND   oa.uploaddatetime BETWEEN :partitioned_start_date AND :partitioned_end_date
         ))OR
    OR (lv_summm_type_indicator = c_summaryType_incrementLoad
                    AND oa.uploaddatetime BETWEEN :sum_startdate AND :sum_enddate )Edited by: Nagaraja Akkivalli on Aug 24, 2011 5:13 PM
    Edited by: Nagaraja Akkivalli on Aug 24, 2011 5:16 PM

  • Merge query error in Where clause

    Following error is coming when i execute the merge query. Anything wrong with this? I am using Oracle 9.2.0.1.
    Query:
    MERGE
         INTO incompletekalls ic
         USING live_small ls
         ON ((ls.callid = ic.callid) AND
         (ls.sdate = ic.sdate) AND
         (ls.stime = ic.stime))
    WHEN MATCHED THEN
         UPDATE
         SET     ic.adate = ls.adate,
              ic.atime = ls.atime,
              ic.edate = ls.edate,
              ic.etime = ls.etime
         WHERE
              ls.sdate = '16-Apr-09' AND ls.stime >= '09:00:00' AND ls.stime <= '11:00:00' AND ((ls.adate IS NULL) OR
              (ls.edate IS NULL))
    WHEN NOT MATCHED THEN
         INSERT (ic.callid,ic.cg,ic.cd,ic.re,ic.opc,ic.dpc,ic.sdate,ic.stime,ic.adate,ic.atime,ic.edate,ic.etime)
         VALUES (ls.callid,ls.cg,ls.cd,ls.re,ls.opc,ls.dpc,ls.sdate,ls.stime,ls.adate,ls.atime,ls.edate,ls.etime)
         WHERE ls.sdate >= '16-Apr-09' AND ls.stime >= '09:00:00' AND ls.stime <= '11:00:00'
    Error:
    SQL> /
    WHERE
    ERROR at line 13:
    ORA-00905: missing keyword

    Hi,
    From looking at the documented examples
    http://www.oracle.com/pls/db92/db92.drilldown?levelnum=2&toplevel=a96540&method=FULL&chapters=0&book=&wildcards=1&preference=&expand_all=&verb=&word=MERGE#a96540
    and on http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:5318183934935
    I think that you cannot use the WHERE in your MERGE like that on 9i...
    Something else I want to warn you for:
    It's a bad idea to store your date and time separated as strings! You'll run into troubles sooner or later, for 100%...
    Use a single DATE column instead, in which you store both the date and time components..

  • Syntax error in Merge Query

    This is the first time i am using Merge Query and the query is
    ;MERGE saSalesStockRecevedSub AS T
       USING @tableSRN AS S
       ON (T.prodCode=S.prodCode AND T.packtypeID=S.packtypeID AND T.batchCode=S.batchCode and T.stockReceiveMainID=S.stockReceiveMainID)
    WHEN NOT MATCHED BY T
        THEN
        INSERT(stockReceiveMainID, prodCode, packtypeID, batchCode, quantityClaim, quantityReceived,reasonId, qQuantity, saleableQty, mfgDefect, slDamageQty, nonSaleableQty, damageQty, breakageQty, leakageQty, expiryQty, remarks,activeStatus,cnCreateSl,cnCreateNsl)
        VALUES(S.stockReceiveMainID, S.prodCode, S.packtypeID, S.batchCode, S.quantityClaim, S.quantityReceived,S.reasonId, S.qQuantity, S.saleableQty, S.mfgDefect, S.slDamageQty, S.nonSaleableQty, S.damageQty, S.breakageQty, S.leakageQty, S.expiryQty,
    S.remarks,'ACTIVE','FALSE','FALSE')
    WHEN MATCHED
        THEN
        UPDATE SET T.quantityClaim=S.quantityClaim, T.quantityReceived=S.quantityReceived,T.reasonId=S.reasonId, T.qQuantity=S.qQuantity, T.saleableQty=S.saleableQty, T.mfgDefect=S.mfgDefect, T.slDamageQty=S.slDamageQty, T.nonSaleableQty=S.nonSaleableQty,
    T.damageQty=S.damageQty, T.breakageQty=S.breakageQty, T.leakageQty=S.leakageQty, T.expiryQty=S.expiryQty, T.remarks=S.remarks
    WHEN NOT MATCHED BY S
        THEN
        DELETE ;
    It showing incorrect syntax near 'T'.
    Please help me.
    Thanks

    Here below is the complete code, hope it will work with you. 
    You should use the key word source and target instead of using S and T
    MERGE saSalesStockRecevedSub AS T
       USING tableSRN AS S
       ON (T.prodCode=S.prodCode AND T.packtypeID=S.packtypeID AND T.batchCode=S.batchCode and T.stockReceiveMainID=S.stockReceiveMainID)
    WHEN NOT MATCHED BY TARGET
        THEN 
        INSERT(stockReceiveMainID, prodCode, packtypeID, batchCode, quantityClaim, quantityReceived,reasonId, qQuantity, saleableQty, mfgDefect, slDamageQty, nonSaleableQty, damageQty, breakageQty, leakageQty, expiryQty, remarks,activeStatus,cnCreateSl,cnCreateNsl) 
        VALUES(S.stockReceiveMainID, S.prodCode, S.packtypeID, S.batchCode, S.quantityClaim, S.quantityReceived,S.reasonId, S.qQuantity, S.saleableQty, S.mfgDefect, S.slDamageQty, S.nonSaleableQty, S.damageQty, S.breakageQty, S.leakageQty, S.expiryQty,
    S.remarks,'ACTIVE','FALSE','FALSE')
    WHEN MATCHED  
        THEN 
        UPDATE SET T.quantityClaim=S.quantityClaim, T.quantityReceived=S.quantityReceived,T.reasonId=S.reasonId, T.qQuantity=S.qQuantity, T.saleableQty=S.saleableQty, T.mfgDefect=S.mfgDefect, T.slDamageQty=S.slDamageQty, T.nonSaleableQty=S.nonSaleableQty,
    T.damageQty=S.damageQty, T.breakageQty=S.breakageQty, T.leakageQty=S.leakageQty, T.expiryQty=S.expiryQty, T.remarks=S.remarks
    WHEN NOT MATCHED BY SOURCE
        THEN 
        DELETE ;
    Working as a Senior Database Analyst & Architect at Ministry of Higher Education in KSA

  • Need help optimizing a merge query

    Hi all, I hope someone can give me some assistance with this. I don't have a lot of experience with Oracle, so any help would be greatly appreciated. I have a MERGE query that I need to optimize as much as possible. I will give as much information as I can in this post.
    Here is the actual query:
          MERGE INTO quick_scene_lookup qsl
          USING (
            SELECT scene.*,
              CASE
                WHEN scene.data_category LIKE 'NOM%'
                  THEN 'NOM'
                WHEN scene.data_category LIKE 'ENG%'
                  THEN 'ENG'
                WHEN scene.data_category LIKE 'VAL%'
                  THEN 'VAL'
                ELSE scene.data_category
              END scn_data_category,
              CASE
                WHEN scene.data_category_original LIKE 'NOM%'
                  THEN 'NOM'
                WHEN scene.data_category_original LIKE 'ENG%'
                  THEN 'ENG'
                WHEN scene.data_category_original LIKE 'VAL%'
                  THEN 'VAL'
                ELSE scene.data_category_original
              END data_category_orig,
              CASE
                WHEN scene.full_partial_scene LIKE 'F%'
                  THEN 'F'
                WHEN scene.full_partial_scene LIKE 'P%'
                  THEN 'P'
                ELSE scene.full_partial_scene
              END scn_full_partial_scene,
              CASE
                WHEN scene.date_entered_lam IS NULL
                    OR scene.deleted = 1
                  THEN 0
                ELSE 1
              END in_lam,
              CASE
                WHEN scene.in_uis LIKE 'Y%'
                  THEN 1
                ELSE 0
              END scn_in_uis,
              CASE
                WHEN scene.data_category LIKE 'NOM%'
                    AND scene.full_partial_scene LIKE 'F%'
                  THEN 1
                ELSE 0
              END monitor,
              CASE
                WHEN scene.date_updated_lam IS NOT NULL
                    AND scene.satellite_sensor_key = 8 -- L7 ETM
                  THEN
                    CASE
                      WHEN intv.match_in_tolerance = 'Y'
                          OR intv.match_in_tolerance = 'N'
                        THEN 0
                      ELSE 1
                    END
                 ELSE 0
              END lam_orphan,
              sat.satellite,
              sat.sensor_id,
              station.station_id,
              intv.match_in_tolerance,
              wrs.wrs_path,
              wrs.wrs_row,
              TO_DATE(SUBSTR(scene.scene_start_time, 0, 17),
                  'YYYY:DDD:HH24:MI:SS') scn_scene_start_time,
              CASE
                WHEN qsl.date_downlinked IS NOT NULL
                    AND scene.date_standing_request IS NOT NULL
                  THEN (qsl.date_downlinked - scene.date_standing_request) * 1440
                ELSE NULL
              END dd_downlinked_marketable
            FROM all_scenes scene
            INNER JOIN lu_satellite sat
              ON (scene.satellite_sensor_key = sat.satellite_sensor_key)
            INNER JOIN ground_stations station
              ON (scene.station_key = station.station_key)
            INNER JOIN all_intervals intv
              ON (scene.landsat_interval_id = intv.landsat_interval_id)
            INNER JOIN worldwide_reference_system wrs
              ON (scene.wrs_key = wrs.wrs_key)
            LEFT OUTER JOIN quick_scene_lookup qsl
              ON (scene.landsat_scene_id = qsl.landsat_scene_id)
            WHERE (scene.job_sequence_key IN (
              SELECT job_sequence_key FROM jobs_subscript_execution_fact
              WHERE job_key = 109)
            OR qsl.landsat_scene_id IS NULL)
            AND scene.scene_version = (
              SELECT MAX(scene_version) FROM all_scenes
              WHERE SUBSTR(landsat_scene_id, 1, 19) =
                SUBSTR(scene.landsat_scene_id, 1, 19))) scenes
          ON (qsl.landsat_scene_id = scenes.landsat_scene_id
            OR (qsl.satellite = scenes.satellite
              AND qsl.station_id = scenes.station_id
              AND qsl.wrs_path = scenes.wrs_path
              AND qsl.wrs_row = scenes.wrs_row
              AND TRUNC(qsl.date_acquired) = TRUNC(scenes.date_acquired)
              AND SUBSTR(qsl.sensor_id, 1, 3) = SUBSTR(scenes.sensor_id, 1, 3)))
          WHEN MATCHED THEN
          UPDATE SET
            data_category = scenes.scn_data_category,
            data_category_original = scenes.data_category_orig,
            date_acquired = scenes.date_acquired,
            date_entered = scenes.date_entered,
            date_standing_request = scenes.date_standing_request,
            date_updated = scenes.date_updated,
            dd_downlinked_marketable = scenes.dd_downlinked_marketable,
            full_partial_scene = scenes.scn_full_partial_scene,
            in_lam = scenes.in_lam,
            in_uis = scenes.scn_in_uis,
            lam_orphan = scenes.lam_orphan,
            monitor = scenes.monitor,
            satellite = scenes.satellite,
            scene_start_time_date = scenes.scn_scene_start_time,
            sensor_id = scenes.sensor_id,
            station_id = scenes.station_id,
            wrs_path = scenes.wrs_path,
            wrs_row = scenes.wrs_row,
            cloud_cover = scenes.cloud_cover
          WHEN NOT MATCHED THEN INSERT(
            qsl_scene_id,
            data_category,
            data_category_original,
            date_acquired,
            date_entered,
            date_standing_request,
            date_updated,
            full_partial_scene,
            in_lam,
            in_moc,
            in_uis,
            lam_orphan,
            landsat_interval_id,
            landsat_scene_id,
            monitor,
            satellite,
            scene_start_time_date,
            sensor_id,
            station_id,
            wrs_path,
            wrs_row,
            cloud_cover)
          VALUES(
            seq_qsl_scene_id.nextval,
            scenes.scn_data_category,
            scenes.data_category_orig,
            scenes.date_acquired,
            scenes.date_entered,
            scenes.date_standing_request,
            scenes.date_updated,
            scenes.scn_full_partial_scene,
            scenes.in_lam,
            0,     -- in_moc will always be 0 for archive inserts
            scenes.scn_in_uis,
            scenes.lam_orphan,
            scenes.landsat_interval_id,
            scenes.landsat_scene_id,
            scenes.monitor,
            scenes.satellite,
            scenes.scn_scene_start_time,
            scenes.sensor_id,
            scenes.station_id,
            scenes.wrs_path,
            scenes.wrs_row,
            scenes.cloud_cover)
        LOG ERRORS INTO ingest_errors('Intervals error')
          REJECT LIMIT 500;All of the columns used in the joins have indexes. Also, all columns referenced in the WHERE clause also have indexes. I have function based indexes on the two columns that are using a function.
    The cost from the explain plan is at 14 million, and this query takes far too long to run. I can post the explain plan if anybody wants it. We are running Oracle 10.2g, and are a data warehouse. Any help I can get on this would be greatly appreciated, I and my dba's are unable to come up with any more ideas. Thanks in advance.

    Well, just in case this might help someone else out, I was able to resolve my issue with the code. It turns out that in the secondary condition of the ON clause for the merge, I had columns that were also being updated. By removing the those columns from the UPDATE clause. It dropped my cost down to 456,000. I was further able to reduce the cost of the query by removing the primary conditional completely. I am a C++ programmer and was counting on a short-circuit OR to speed up the process. Anyway, my cost is now down to 215,000, and all is good here.
    Thanks.

  • Oracle Merge query

    Hi ,
    I am writing a merge query for a Java application. I have a screen and I am going to take the values in the screen and check if those values exist in the database. If they exist, then I will have to update the data, else I will have to insert the data.
    The query is like
    MERGE INTO XYZ USING
    (SELECT BONUS_ID,CUST_NBR FROM XYZ)B ON
    (B.BONUS_ID = 2027 and B.CUST_NBR='181258225')
    WHEN MATCHED THEN UPDATE SET
    CUST_TYPE= 'S', REV_AMT= 123, POUND_TOTAL= 123, PKG_TOTAL= 123 WHERE
    CUST_NBR = '181258225'
    WHEN NOT MATCHED THEN INSERT
    But this query is not working. I get the "Missing Keyword"

    I meant nothing else
    update xyz set ... where ...;
    and
    insert into xyz select ... from xyz where ...;
    I wrote "When I check B.Bonus_ID it refers to the BonusID from XYZ table".
    Let me give you one example with SCOTT schema.
    I hope it illustrates well my concern of your
    statement:
    SQL> select ename, empno, sal from emp;
    &nbsp
    ENAME                     EMPNO        SAL
    SMITH                      7369        800
    ALLEN                      7499       1600
    WARD                       7521       1250
    JONES                      7566       2975
    MARTIN                     7654       1250
    BLAKE                      7698       2850
    CLARK                      7782       2450
    SCOTT                      7788       3000
    KING                       7839       5000
    TURNER                     7844       1500
    ADAMS                      7876       1100
    JAMES                      7900        950
    FORD                       7902       3000
    MILLER                     7934       1300
    &nbsp
    14 rows selected.
    &nbsp
    SQL> merge into emp using (select * from emp) b
      2  on (b.ename = 'KING')
      3  when matched then update set sal = 1000
      4  when not matched then insert (emp.empno, emp.ename, emp.deptno, emp.sal
      5  values(-b.empno, b.ename, b.deptno, 0)
      6  /
    &nbsp
    27 rows merged.
    &nbsp
    SQL> select ename, empno, sal from emp;
    &nbsp
    ENAME                     EMPNO        SAL
    SMITH                     -7369          0
    ALLEN                     -7499          0
    WARD                      -7521          0
    JONES                     -7566          0
    MARTIN                    -7654          0
    BLAKE                     -7698          0
    CLARK                     -7782          0
    SCOTT                     -7788          0
    TURNER                    -7844          0
    ADAMS                     -7876          0
    JAMES                     -7900          0
    FORD                      -7902          0
    MILLER                    -7934          0
    SMITH                      7369       1000
    ALLEN                      7499       1000
    WARD                       7521       1000
    JONES                      7566       1000
    MARTIN                     7654       1000
    BLAKE                      7698       1000
    CLARK                      7782       1000
    SCOTT                      7788       1000
    KING                       7839       1000
    TURNER                     7844       1000
    ADAMS                      7876       1000
    JAMES                      7900       1000
    FORD                       7902       1000
    MILLER                     7934       1000
    &nbsp
    27 rows selected.Rgds.

  • Simple Query Question - How do I return the Last 3 records of a Table?

    Question.
    For example, I have a table that has 50 records.
    How do I, specify in SQL to only return the last 3 records of the table.
    Select a.* from table a where ????

    I was just trying to show an example to a friend on
    how something like this would work and if it was even possible. But it won't work. Here's a simple example:
    SQL> create table emp
      2  (id)
      3  as
      4  select object_id
      5  from   all_objects
      6  order  by object_id;
    Table created.
    SQL> select *
      2  from  (select rownum rn
      3               ,b.*
      4         from   emp b)
      5  where  rn > ( select (max(rownum) - 3)
      6                from    emp)
      7  ;
            RN         ID
         40830      55891
         40831      55892
         40832      55893So far, so good. These are the "last 3" rows inserted. Now delete a bunch of rows and insert 3 new ones:
    SQL> delete emp where id < 40000;
    33423 rows deleted.
    SQL> commit;
    Commit complete.
    SQL> insert into emp values (60000);
    1 row created.
    SQL> insert into emp values (60001);
    1 row created.
    SQL> insert into emp values (60002);
    1 row created.
    SQL> commit;
    Commit complete.
    SQL> select *
      2  from  (select rownum rn
      3               ,b.*
      4         from   emp b)
      5  where  rn > ( select (max(rownum) - 3)
      6                from    emp)
      7  ;
            RN         ID
          7410      55891
          7411      55892
          7412      55893Here's the problem. Even though the "last 3 rows" are 60000 - 60002, I still get the same ones as the first query.

  • Issue with "read by other session" and a parallel MERGE query

    Hi everyone,
    we have run into an issue with a batch process updating a large table (12 million rows / a few GB, so it's not that large). The process is quite simple - load the 'increment' from a file into a working table (INCREMENT_TABLE) and apply it to the main table using a MERGE. The increment is rather small (usually less than 10k rows), but the MERGE runs for hours (literally) although the execution plan seems quite reasonable (can post it tomorrow, if needed).
    The first thing we've checked is AWR report, and we've noticed this:
    Top 5 Timed Foreground Events
    Event     Waits     Time(s)     Avg wait (ms)     % DB time     Wait Class
    DB CPU           10,086           43.82     
    read by other session     3,968,673     9,179     2     39.88     User I/O
    db file scattered read     1,058,889     2,307     2     10.02     User I/O
    db file sequential read     408,499     600     1     2.61     User I/O
    direct path read     132,430     459     3     1.99     User I/OSo obviously most of the time was consumed by "read by other session" wait event. There were no other queries running at the server, so in this case "other session" actually means "parallel processes" used to execute the same query. The main table (the one that's updated by the batch process) has "PARALLEL DEGREE 4" so Oracle spawns 4 processes.
    I'm not sure how to fix this. I've read a lot of details about "read by other session" but I'm not sure it's the root cause - in the end, when two processes read the same block, it's quite natural that only one does the physical I/O while the other waits. What really seems suspicious is the number of waits - 4 million waits means 4 million blocks, 8kB each. That's about 32GB - the table has about 4GB, and there are less than 10k rows updated. So 32 GB is a bit overkill (OK, there are indexes etc. but still, that's 8x the size of the table).
    So I'm thinking that the buffer cache is too small - one process reads the data into cache, then it's removed and read again. And again ...
    One of the recommendations I've read was to increase the PCTFREE, to eliminate 'hot blocks' - but wouldn't that make the problem even worse (more blocks to read and keep in the cache)? Or am I completely wrong?
    The database is 11gR2, the buffer cache is about 4GB. The storage is a SAN (but I don't think this is the bottleneck - according to the iostat results it performs much better in case of other batch jobs).

    OK, so a bit more details - we've managed to significantly decrease the estimated cost and runtime. All we had to do was a small change in the SQL - instead of
    MERGE /*+ parallel(D DEFAULT)*/ INTO T_NOTUNIFIED_CLIENT D /*+ append */
      USING (SELECT
          FROM TMP_SODW_BB) S
      ON (D.NCLIENT_KEY = S.NCLIENT_KEY AND D.CURRENT_RECORD = 'Y' AND S.DIFF_FLAG IN ('U', 'D'))
      ...(which is the query listed above) we have done this
    MERGE /*+ parallel(D DEFAULT)*/ INTO T_NOTUNIFIED_CLIENT D /*+ append */
      USING (SELECT
          FROM TMP_SODW_BB AND DIFF_FLAG IN ('U', 'D')) S
      ON (D.NCLIENT_KEY = S.NCLIENT_KEY AND D.CURRENT_RECORD = 'Y')
      ...i.e. we have moved the condition from the MERGE ON clause to the SELECT. And suddenly, the execution plan is this
    OPERATION                           OBJECT_NAME             OPTIONS             COST
    MERGE STATEMENT                                                                 239
      MERGE                             T_NOTUNIFIED_CLIENT
        PX COORDINATOR
          PX SEND                       :TQ10000                QC (RANDOM)         239
            VIEW
              NESTED LOOPS                                      OUTER               239
                PX BLOCK                                        ITERATOR
                  TABLE ACCESS          TMP_SODW_BB             FULL                2
                    Filter Predicates
                      OR
                        DIFF_FLAG='D'
                        DIFF_FLAG='U'
                  TABLE ACCESS          T_NOTUNIFIED_CLIENT       BY INDEX ROWID    3
                    INDEX               AK_UQ_NOTUNIF_T_NOTUNI    RANGE SCAN        2
                      Access Predicates
                        AND
                          D.NCLIENT_KEY(+)=NCLIENT_KEY
                          D.CURRENT_RECORD(+)='Y'
                      Filter Predicates
                        D.CURRENT_RECORD(+)='Y' Yes, I know the queries are not exactly the same - but we can fix that. The point is that the TMP_SODW_BB table contains 1639 rows in total, and 284 of them match the moved 'IN' condition. Even if we remove the condition altogether (i.e. 1639 rows have to be merged), the execution plan does not change (the cost increases to about 1300, which is proportional to the number of rows).
    But with the original IN condition (that turns into an OR combination of predicates) in the MERGE ON clausule, the cost suddenly skyrockets to 990.000 and it's damn slow. It seems like a problem with cost estimation, because once we remove one of the values (so there's only one value in the IN clausule), it works fine again. So I guess it's a planner/estimator issue ...

  • Oracle 10g and parallel query question

    Hi Oracle on SAP Gurus!
    We are currently thinking of activating parallel query for certain segments (large application tables and indexes). We searched in SAPNet and SDN and have also studied the SAP Note 651060. But we did not find a complete answer to the following question which is very important for us:
    Which kinds of queries (despite from full table scan and index scan in partitioned indexes) support parallel queries and which ones do not support parallel queries?
    This is important for us to find out whether we have candidates for parallel queries or not.
    Thanx for any hint!
    Regards,
    Volker

    But why do you not propose to use parallel query in OLTP systems?
    If the queries are accessed very frequently you will just run out of cpu and io ressources. OLTP systems are (historical) typically multi user systems. You can off course use PQ for 'single user' activities, like index rebuilds, some batchjobs, but you shouldn't do for frequent user queries.
    If you have time look at this interesting Article [Suck It Dry - Tuning Parallel Execution|http://doug.burns.tripod.com/px.html]
    It is quite old, and you don't have to read all tech details, but i recommend having a look at the conclusions at the end.
    May it make sense to use partitioning of these tables in conjunction with parallel query?
    I know some guys, who do partitioning on OLTP systems, even SAP systems. But they don't use PQ then. The use partitioning to work on a smaller set of data. In your case the range scans, would need to scan only one partition, saving buffer cache and effectively speeding up execution. So you don't need PQ to scan all partitions at all, this would be a typical OLAP approach.
    Best regards
    Michael

  • General JPA query question

    Hello world,
    I'm new to JPA 2.0 and there are few things I don't understand.
    BTW: I can't figure out the keywords to search for this question, so please pardon me if it's one of the most asked.
    Using the Preview, I've seen that alignment went straight to Hell, so I tried to make this as readable as I could using pipes in place of white spaces in the result sets.
    I have a couple of tables:
    CUST table (for customers):
    CUST_ID (pk, integer)
    CUST_NAME (varchar)
    ORD table (for orders):
    ORD_ID (pk, integer)
    ORD_STATUS (char) can be: N for new, S for shipped, D for delivered
    CUST_ID (fk, integer)
    The relationship is, of course, a "one to many" (every customer can place many orders).
    Content of the tables:
    CUST_ID|CUST_NAME
    1|elcaro
    2|tfosorcim
    3|elppa
    ORD_ID|ORD_STATUS|CUST_ID
    2|N|1
    3|N|1
    4|N|1
    5|S|1
    6|S|1
    7|D|1
    8|D|1
    9|D|1
    10|D|2
    11|N|2
    12|S|3
    13|S|3
    Here's how I annotated my classes:
    Customer.java:
    @Entity(name = "Customer")
    @Table(name = "CUST")
    public class Customer implements Serializable
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "CUST_ID")
    private Integer id;
    @Column(name = "CUST_NAME")
    private String name;
    @OneToMany(mappedBy = "customer")
    private List<Order> orders;
    // Default constructor, getters and setters (no annotations on these)
    Order.java:
    @Entity(name = "Order")
    @Table(name = "ORD")
    public class Order implements Serializable
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "ORD_ID")
    private Integer id;
    @Column(name = "ORD_STATUS")
    private Character status;
    @ManyToOne
    @JoinColumns
    @JoinColumn(name = "CUST_ID", referencedColumnName = "CUST_ID")
    private Customer customer;
    // Default constructor, getters and setters (no annotations on these)
    Everything works just fine, the following JPQL query yields the results I expected:
    select c from Customer c
    it returns three objects of type Customer, each of which contains the orders that belong to that customer.
    But now, I want to extract the list of customers that have orders in status 'N', along with the associated orders (only the status 'N' orders, of course).
    Back in the good ol' days I would have written an SQL query like this:
    select c.cust_id, c.cust_name, o.ord_id, o.ord_status
    from cust c
    inner join ord o on (o.cust_id = c.cust_id)
    where o.ord_status = 'N'
    and it would have returned the following result set:
    CUST_ID|CUST_NAME|ORD_ID|ORD_STATUS
    1|elcaro|2|N
    1|elcaro|3|N
    1|elcaro|4|N
    2|tfosorcim|11|N
    The following JPQL query, however, doesn't yield the expected results:
    select distinct c from Customer c join c.orders o where o.status = 'N'
    it returns the correct set of customers (customer 'elppa' doesn't have any status 'N' order and is correctly excluded), but each customer contains the full set of orders, regardless of the status.
    It seems that the 'where' clause is only evaluated to determine which set of customers has to be extracted and then the persistence provider starts to navigate the relationship to extract the full set of orders.
    Thinking a little about it, I must admit that it makes sense.
    I then tried out another JPQL query:
    select c, o from Customer c join c.orders o where o.status = 'N'
    this JPA query yields results that are similar to the ones produced by the previous SQL query: each result (4 results as expected) is a 2-object array, the first object is of type Customer and the second object is of type Order. But, again, the objects of type Customer contain the full set of related orders (as I expected, this time). Not to mention the fact that now the orders are not contained in the Customer objects, but are returned separately, just as in an SQL result set.
    Now the question is:
    Is it possible to write a JPA query that filters out, not only the customers that don't have an order in status 'N', but the related orders (fetched during relationship navigation) that are not in status 'N' as well?
    What I'd like to be able to get is a 2-customer result where each customer contains only its status 'N' orders.
    I read the Java EE 6 Tutorial and one of the examples (the Order Application) has a schema that is similar to mine, but I couldn't find a query like this (in the downloaded source code).
    Although I think the above is standard behavior, I use an Oracle Weblogic 12c server (through its Eclipse adapter) and the persistence provider appears to be EclipseLink.
    Thanks in advance.
    Best regards,
    Stefano
    Edited by: user11265230 on 17-apr-2012 14.11

    Hello,
    When returning an entity from JPQL, it gives you the entity as it is in the database. Your "select distinct c from Customer c join c.orders o where o.status = 'N'" is asking for all customers that have an order with a status of 'N', so that is what it gives you. There is no condition to filter anything on the relationship when building the Customer object in JPA - doing so would mean returning a managed entity that does not reflect what is in the database. This would affect other queries, since JPA requires that queries return the same instance of an entity regardless of the query that is used to bring it back. So a query using your "where o.status = 'N'" would cause conflicting results when used with a query using "where o.status = 'Y'". And these queries would make the EntityManager unable to determine what has changed on the returned objects.
    EclipseLink does have the ability to filter over relationships, it is just not available through standard JPA and I would strongly discourage it. Instead of querying for Customers, why not change the query to get Orders instead -
    "select o from Customer c join c.orders o where o.status = 'N'". Assuming Orders have a ManyToOne back reference to their Customer, this will mean you do not need to travers the Customer-> order relationship. If using
    "select c, o from Customer c join c.orders o where o.status = 'N'"
    I am not sure why you would use the orders from the returned customers instead of the orders returned in the results though.
    You could also return "select c.id, c.name, o.id, o.status from Customer c join c.orders o where o.status = 'N'" which is the equivalent of what you would get from the SQL you initially posted.
    Regards,
    Chris

  • Left Join Query Question

    Version 10.2.0.4.0
    I have a question on the expected behavior of the query below.
    When I run the query below with the constraint on t1.partid = 789,  I get the query result t2.Indicator showing "SPECIAL" as expected.
    However, if I remove the constraint, and return all orders and parts, for the "789" part, the Indicator column is null.
    select t1.orderid, t1.partid, t2.Indicator
    from Orders a left outer join
    select partid, 'SPECIAL' as Indicator
    from vendors
    where vendorname like '%ABC%'
    ) t2
    on t1.partid = t2.partid
    where t1.partid = '789'
    I can address the issue with a case statement (below) or likely restructuring into a better statement. 
    But I'm just curious if this is expected or if there is some SQL rule being violated in the first example.
    I tried to search for this to see if it was already addressed but didn't have much luck.
    This works:
    select t1.orderid, t1.partid,
    case when t1.partid is not null then "SPECIAL" else null end as Indicator
    from Orders a left outer join
    select partid, 'SPECIAL' as Indicator
    from vendors
    where vendorname like '%ABC%'
    ) t2
    on t1.partid = t2.partid

    Sorry, it's been a while since I posted and should have read the rules.  And I didn't properly reference the alias.  So Post #1 was bad. 
    When I mockup a small set of data (shown below), I don't get the error.  The original query actually joins to a few other (seemingly) irrelevant tables and I tried to simplify it here  So I guess if I can't replicate it, then there might not be much assistance that can be provided.
    This was more of a curiousity than anything else to see if perhaps someone came across this before.
    For what it's worth:
    create table t1 (orderid number,
                 partid varchar2(20)
    create table t2
            (vendorid varchar2(20),
             partid varchar2(20)
    insert into t1 values(1, '123');
    insert into t1 values(2, '456');
    insert into t1 values(3, '789');
    insert into t2 values ('ABC','789');
    insert into t2 values ('DEF','123');
    insert into t2 values ('EFG','456');
    insert into t2 values ('ABC','7891');
    insert into t2 values ('DEF','1231');
    insert into t2 values ('EFG','4561');
    select t1.orderid, t1.partid, t2.Indicator
    from t1 left outer join
    select partid, 'SPECIAL' as Indicator
    from t2
    where vendorid like '%ABC%'
    ) t2
    on t1.partid = t2.partid
    the query that gives unexpected behavior is (although I can't replicate on this simplified version):
    select t1.orderid, t1.partid, t2.Indicator
    from t1 left outer join
    select partid, 'SPECIAL' as Indicator
    from t2
    where vendorid like '%ABC%'
    ) t2
    on t1.partid = t2.partid

  • SQL Query Question

    Hi,
    I am trying to filter my output from the query based on some conditions but not able to figure out how. May be I am just overlooking at the issue or is it something tricky.
    So, I have a query returning 4 rows of output out of which I need to filter the rows. I have created a table from the result of the query that I need to filter to make it simple. So below is my create table script and values that are obtained from my original query.
    CREATE TABLE TEMPACCT
      SOURCEKEY           NUMBER,
      FLAG                VARCHAR2(1),
      ITEMID              NUMBER(9)                 ,
      ITEMNAME            VARCHAR2(10)               ,
      ITEMKEY             NUMBER(9)                
    Insert into tempacct values (0, 'N', 100, 'ITEM1' , 9647);
    Insert into tempacct values (0, 'N', 200, 'ITEM2' , 9648);
    Insert into tempacct values (9648, 'N', 100, 'ITEM3' , 9813);
    Insert into tempacct values (9647, 'Y', 100, 'ITEM4' , 9812);
    SQL> select * from tempacct;
    SOURCEKEY F     ITEMID ITEMNAME      ITEMKEY
             0 N        100 ITEM1            9647
             0 N        200 ITEM2            9648
          9648 N        100 ITEM3            9813
          9647 Y        100 ITEM4            9812
    SQL> Tempacct table is the table created from the resultset of my original query.
    So from the above output, what I need is 3 rows. The logic to filter out the row is - If any of the row thathas sourcekey that is same as Itemkey in any of the 4 rows and flag is Y then remove the row which have flag =N and only display the one with Falg = Y.
    Ok, so, in this case the desired output would be
    SOURCEKEY F     ITEMID ITEMNAME      ITEMKEY
             0 N        200 ITEM2            9648
          9648 N        100 ITEM3            9813
          9647 Y        100 ITEM4            9812So here we compared between the first row and the fourth row, and since the sourcekey in fourth row is same as itemkey in first row and Flag is 'Y' for fourth row, we keep 4th row and remove the first row since the flag is 'N'. (and sourcekey is 0. the row that gets removed will always have sourcekey =0) .
    SQL> select * from v$version;
    BANNER
    Oracle Database 10g Release 10.2.0.4.0 - 64bit Production
    PL/SQL Release 10.2.0.4.0 - Production
    CORE    10.2.0.4.0      Production
    TNS for Linux: Version 10.2.0.4.0 - Production
    NLSRTL Version 10.2.0.4.0 - ProductionAppreciate your help.

    Hi,
    ARIZ wrote:
    Although the original question is already been answered, I had another small modification to the same question and also seeking some clarification. I do not want to open a new thread just for a similar question.I think you'll get better replies faster if you do start a new thread.
    Not counting this one, there have been 13 replies to this thread. Not many people who havn't already been participating in this thread are going to start reading a thread with 13 replies. Those who do are going to waste a lot of time reading about issues that have already been resolved, and the are likely to understand the remaining issues incorrectly.
    I have been following the thread from the beginnning, and I'm starting to get confused about what the unresolved issues are.
    I believe there are two things you still need:
    (1) An explanation of the solution I posted yesterday, involving the analytic COUNT function.
    (2) A solution for a new problem involving the same tables
    If I got that wrong, start a new thread, asking just what you need to know. Copy any relevant parts (like the CREATE TABLE and INSERT statements) from this thread. You can include a link to this thread, but do your best to make sure people don't have to use it.
    I realize that's more work for you, but getting the best results, and getting them quickly, sometimes does require more work.
    <h2>(1) An explanation of the solution I posted yesterday, involving the analytic COUNT function.</h2>
    ARIZ wrote:
    Hi Frank,
    Just out of curiosity, I was trying to understand the Count analytical function that you have used in the solution.
                    COUNT ( CASE
                                 WHEN  ac.flag = 'Y'
                           THEN  1
                             END
                        ) OVER ( PARTITION BY  CASE
                                                   WHEN  sourcekey = 0
                                       THEN  acctkey
                                       ELSE  sourcekey
                                               END
                                  )     AS y_cntSo what I am thinking is, this would first partition the row with acctkey ( where sourcekey =0) and sourcekey and then within that partition, it will check whether ac.flag = Y or not, if it is 'Y' then it would return count as 1 else 0. Am I correct? In the mean time I am also reading the tutorials on Count() analytical query. I'm not sure I understand your explanation.
    This is not partitioning first by x, and then by y. There is only one expression in the PARTITION BY clause. Most often, a PARTITION BY clause refers to some column in the table, for example:
    SELECT  ename
    ,       job
    ,       sal
    ,       AVG (sal) OVER (PARTITION BY job)  AS avg_sal_for_job
    FROM    scott.emp;This divides the result set into mutually exclusive parts; there will be as many such parts as there are distinct values for the PARTITION BY column. In the simple query above, if there happen to be 5 different values for job, you will get 5 independent averages.
    In your problem, there is no one column that defines a partition. That is, these two rows belong to the same partition:
    . SOURCEKEY F   ACCTKEY
             0 N       9647
          9647 Y       9812even though none of the 3 columns are the same. We could create a view that had a single column, telling to which partition each row belonged, like this:
    . SOURCEKEY F   ACCTKEY PART_NUM
             0 N       9648     9648
             0 N       9647         9647
          9648 N       9813         9648
          9647 Y       9812         9647where part_num is the result of a CASE expression:
    CASE
        WHEN  sourcekey = 0
        THEN  acctkey
        ELSE  sourcekey
    ENDWe could then use that new column, part_num, in a (very simple) PARTITION BY clause. But there is no need to create a view, even an in-line view, for that: we can (and I did) use the CASE expression directly in a (not so simple) PARTITION BY clause.
    Why did I use COUNT? The important thing about each partition is whether or not it includes any rows with flag='Y'. I don;t know of any function that directly answers that question. There are lots of ways to get the correct answer, but I think the one that corresponds most closely to the question we really want to ask:
    "Do any rows have flag='Y'?" is
    "How many rows have flag='Y'?"
    The analytic function COUNT (x) returns a number (possibly 0) of rows in the partition where x is not NULL. So, as the argument to COUNT, I used
    CASE
        WHEN  ac.flag = 'Y'
        THEN  1
    --  ELSE  NULL          -- I did not explicitly say this, but it is the default
    ENDwhich returns either
    (a) the literal number 1 or
    (b) NULL
    Instead of the literanl number 1, I could have used any literal or expression, of any data type, that is not NULL). all that matters is we produce something non-NULL for COUNT to count.
    <h2>(2) A solution for a new problem involving the same tables</h2>
    Also, I was trying to modify this query to fit my other similar requirement where I would need following output
    Original output:
    SOURCEKEY F    ACCTKEY
    0 N       9648
    0   N      9647
    9648 N       9813
    9647 Y       9812
    So, the query should be smart enough to return only the last two rows where sourcekey >0 which is
    SOURCEKEY F    ACCTKEY
    9648 N       9813
    9647 Y       9812
    And In case there are only first two 2 rows in the table then , it should return only those two row and not check for sourcekey > 0 which would be .
    SOURCEKEY F    ACCTKEY
    0 N       9648
    0   N      9647 Is it something that I should be using analytical function to solve this requirement. I am trying to accomplish this new requirement.If I understand this problem correctly, it does indeed involve mutually exclusive divisions, but in this problem, the divisions correspond more closely to a single column in the table. We want to divide the table into two mutually exclusive groups:
    (A) rows where soucekey > 0, and
    (B) rows where sourcekey = 0
    We could do that with a CASE expression, but there happens to be a built-in function that works very nicely.
    SIGN (sourcekey) returns
    (A) 1 if sourcekey > 0, and
    (B) 0 if sourcekey = 0
    But what do we want to do with those divisions? We want to display rows only from the "best" of those divisions, where division (A) is coinsidered "better" than division (B). That is, if there are any rows in division (A), then we want to display only rows in division (A), but if there are no rows in division (A), then (and only then) we want to display rows in divison (B).
    This is an example of a Top-N Query , where we want to display N items from the top of an ordered list. A typical top-N query uses an analytic function (either ROW_NUMBER, RANK or DENSE_RANK, depending on how we want to handle ties) to assign numbers to each row (lower numbers for the "better" rows), and then uses "WHERE f <= n" to display only the n "best" ones. (A special case, though a very common one, is where N=1, that is, we're only interested in the row (or rows, if there happens to be a tie) with the "best" value. In this case, most people find it cleare to say "WHERE f = 1" ratehr than "WHERE f <= 1". Your problem is an exmple ot that special case.)
    SELECT  sourcekey
    ,     flag
    ,     acctkey
    FROM     (
             SELECT  ac.sourcekey
             ,         NVL (ac.flag, 'N')     AS flag
             ,         ac.acctkey
             ,         DENSE_RANK () OVER (ORDER BY  SIGN (sourcekey)     DESC)     AS division_num
                FROM    itemtable     i
             ,         finance     f
             ,         acct     ac
               WHERE   i.itemtableid1      = f.parentid1
               AND         i.itemtableid2      = f.parentid2
             AND         f.financekey      = ac.financekey
               AND         i.parenttableid      = 19063
    WHERE     division_num     = 1
    ;Notice I talked about "mutually exclusiive *divisions* " above, not "mutually exclusive *partitions* ".
    There is no PARTITION BY in the analytic clause above. PARTITION BY means we want a separate, independent caluclation for each partition. Here, we want one single numbering for the entire result set.
    We want all rows that tie for the "best" to be numbered 1, so we have to use DENSE_RANK (or RANK) rather than ROW_NUMBER.

  • Urgent , Two Query questions ...

    Hello everybody ,
          i have created a query in our production system . but i found some people can change my query setting (ex : my local fileds & selection fields ) , has any one can tell me how can i disable the 'Change' function in 'SQ01' ? many thanks !
    (i also use 'su24' to check the authorzation object in 'SQ01' , but i don't know which one can help me to solved this case)
          another question that is when i execute the query i found one of the field's sequence was wrong . but this query is used everyday & nobody has changed it . but when i use  sort this function to make it & it seems ok . therefore i think the problem is in the table index , right ? Has anyone can tell me how to check it ?
    Best Regards,
    Carlos

    hi Ramki
         the query is made by ourselves . the data is only fetched from the billing table (vbrk & vbak) . but today i found some filed's sequence was wrong & i don't know what cause this .
    another problem is that could you tell me how to disable 'Change' function in 'SQ01' ?
    many thanks ~
    Best Regards,
    Carlos

Maybe you are looking for

  • How can I find outliers in a DIAdem report using LabVIEW

    I am new to DIAdem and I am trying to take a DIAdem report and find the outliers and mark them with an 'X'. I found an example of this but it uses a VB script. The example has a constant to determine what is an outlier. I need this to be a variable.

  • Web Gallery vs. iWeb?

    I'm not sure I understand the difference between the Web Gallery and iWeb. You can add galleries on both? How do you remove a gallery from the Web Gallery after you install it? I was trying to install multiple galleries by doing the shift click then

  • Workflow on folder level to update another list

    Hi there, I have folder structure like folder1/folder2/folder3 there are wiki pages in these folders When I create a new wiki page in one of the folders say folder3 I want an item to be created in another list which has name same as the wiki page nam

  • Difference of Mac OSX 10.4.6 and Mac OSX 10.4.6 Combo

    Hi, Does anyone know the differences among the two? Thanks.

  • Gray Screen of Death on boot

    Hello all, I was using my white Macbook earlier today. I put it to sleep, and then some hours later I woke it up and used it a little. I then restarted it, and now I get the error screen (seen here: http://4.bp.blogspot.com/UqUwVPikChs/SKLhZ624D6I/AA