UPDATE on the same table in the sub query

DB version: 11.2

We have a table called SHP_GC_TRACK, which has about 8 million records with partitions. In the below UPDATE, it updates a column based on the SELECT on the same table in a subquery.
UPDATE shp_gc_track a
   SET f_tran_proc  = 'Y'
 WHERE last_update_date <
          (SELECT MAX (last_update_date)
             FROM shp_gc_track b
            WHERE a.shp_trx_rowid = b.shp_trx_rowid
              AND a.c_shp_inst = b.c_shp_inst
              AND a.f_tran_proc  = b.f_tran_proc 
              AND b.f_ltr_received = 'D'
              AND f_rec_code IN ('G', 'W')
              AND b.f_rec_status = 'B'
              AND b.c_shp_inst = :b1
              )
   AND a.c_shp_inst = :b1
   AND a.f_ltr_received = 'D'             -----------------> part of composite index
   AND a.f_tran_proc  = 'N'              -----------------> part of composite index
   AND a.f_rec_code IN ('G', 'W')      --------------> part of composite index  
   AND a.f_rec_status = 'B';              -----------------> part of composite index  
This UPDATE takes a long time to run and sometimes get hung up.

We have a composite index on four columns f_ltr_received, f_rec_code, f_rec_status and f_tran_proc. Explain the plan shows that this composite index is used.



Any way to rewrite this query or suggestion?

Steve_74 wrote:
DB version: 11.2

We have a table called SHP_GC_TRACK, which has about 8 million records with partitions. In the below UPDATE, it updates a column based on the SELECT on the same table in a subquery.

UPDATE shp_gc_track a
SET f_tran_proc  = 'Y'
WHERE last_update_date <
(SELECT MAX (last_update_date)
FROM shp_gc_track b
WHERE a.shp_trx_rowid = b.shp_trx_rowid
AND a.c_shp_inst = b.c_shp_inst
AND a.f_tran_proc  = b.f_tran_proc
AND b.f_ltr_received = 'D'
AND f_rec_code IN ('G', 'W')
AND b.f_rec_status = 'B'
AND b.c_shp_inst = :b1
)
AND a.c_shp_inst = :b1
AND a.f_ltr_received = 'D'             -----------------> part of composite index
AND a.f_tran_proc  = 'N'              -----------------> part of composite index
AND a.f_rec_code IN ('G', 'W')      --------------> part of composite index
AND a.f_rec_status = 'B';              -----------------> part of composite index  

This UPDATE takes a long time to run and sometimes get hung up.

We have a composite index on four columns f_ltr_received, f_rec_code, f_rec_status and f_tran_proc. Explain the plan shows that this composite index is used.

Any way to rewrite this query or suggestion?

Setting updates with subqueries may be difficult: (.) Unfortunately my suggestions below are of the try-it-and-see-what-happens variety - nothing of certain

First of all, check the index. Is it bitmap or tree? If the tree to see if the more restrictive columns are listed first - this can help with effectiveness of b-tree indexes. Also if the tree a composite bitmap for columns with lots of repeat values instead could help

Its a correlated subquery so that you cannot run just the subquery first put the result in a scalar varaiable and using the variable in the SQL instead. You can try putting the keys w/join subuqery results in a TWG first to use TWG in SQL to see if I/O is reduced together during these two operations.

You have the license for the parallel query option? Using parallel DML (this must be activated manually) can help. Check the documentation of the ALTER SESSION command to do so. In addition, the PARALLEL_INDEX() indicator could help

Display the SQL execution plan

Tags: Database

Similar Questions

  • Order By in the Sub query

    We cannot use ORDER BY in the Sub query.
    select * from emp where emp_no in (select emp_id from dept order by dept_no )
    Get the below error
    ORA-00907: missing right parenthesis

    Hello

    user13024762 wrote:
    To get the number of EMP table for maximum number of dept dept

    If this is what you want, then do something like this:

    select  *
    from      emp
    where      emp_no in (
                          select    MAX (emp_no) KEEP (DENSE_RANK LAST ORDER BY dept_no NULLS FIRST)
                   from      dept
                )
    ;
    

    or maybe

    select  *
    from      emp
    where      emp_no  = (
                          select    emp_no
                   from      dept
                   where     dept_no = (
                                                    SELECT  MAX (dept_no)
                                 FROM    dept
                                                 )
                )
    ;
    

    Depending on what you want in the case of a tie.

    select * from emp where emp_no in (select emp_no from dept where rownum =1 order by dept_no desc)
    

    The subquery that you posted above does not necessarily return the line containing the largest dept_no, since ROWNUM is affected before ORDER BY is done.

    I hope that answers your question.
    If not, post a small example of data (CREATE TABLE and only relevant columns, INSERT statements) for all tables and also post the results desired from these data.
    Explain how you get these results from these data.

  • FETCH ONE RECORD IN THE SECOND TABLE OF CORRELATED SUB QUERY

    Hi all

    I have provided the script below, I want to single fecth record in the second table in the join query,

    based on the example below, I want to go get one record of the table emp2 what matches with the emp_id of table emp1, please note emp2 may contain more record for the emp_id emp1 which respects

    all records can be selected in the table emp2.

    DROP TABLE emp1.

    CREATE TABLE emp1 (emp_id NUMBER);

    INSERT INTO emp1 VALUES (1);

    INSERT INTO emp1 VALUES (2);

    COMMIT;

    DROP TABLE emp2.

    CREATE TABLE emp2 (emp_id NUMBER, emp_name VARCHAR2 (100));

    INSERT INTO emp2 VALUES (1, 'Name1');

    INSERT INTO emp2 VALUES (2, 'Name2');

    INSERT INTO emp2 VALUES (1, 'Name3');

    INSERT INTO emp2 VALUES (2, 'Conjoint4');

    COMMIT;

    SELECT * from emp1.

    SELECT * from emp2.

    SELECT T1. EMP_ID, MIN (T2. EMP_NAME)

    FROM EMP1, EMP2 T2 T1

    WHERE T1. EMP_ID = T2. EMP_ID

    GROUP T1. EMP_ID;

    My output should be the same as the result set of query above, but I don't want this logic, please provide the solution by using a different logic, thanks in advance.

    2811876 wrote:

    Thanks for your comments :-)

    My business logic will change to 'Fetch N second timeline table', that's the reason why I asked for a different approach, if I use max, min to achieve this does not allow me to evolve dynamically.

    Although logic has not been expressed at all in your original question, so good job I asked.

    You could do something like:

    SQL > ed
    A written file afiedt.buf

    1 with emp1 (select 1 as the emp_id of union double all the)
    2. Select 2 double
    3               )
    4, emp2 (select 1 as emp_id, 'name 1' as emp_name double union all
    5. Select "name 2' Union double every 2
    6 select 1, 'name' 3' from dual union all
    7. Select 2, 'name 4' double union all.
    8 select 1, 'name 5' from dual union all '.
    9 select 2, 'name 6' from dual '.
    10               )
    11-
    12. end of test data
    13-
    14 select emp_id, emp_name
    15 of)
    16 select t1.emp_id, t2.emp_name
    17, row_number() over (partition by order of t2.emp_name t1.emp_id) rn
    emp1 t1 18
    19 join t2 emp2 (t1.emp_id = t2.emp_id)
    20       )
    21 * where rn<=>
    SQL > /.

    Enter the value for rows_required: 1
    21 Alumni: where rn<=>
    21 news: where rn<=>

    EMP_ID EMP_NA
    ---------- ------
    1 name 1
    2 name 2

    SQL > /.
    Enter the value for rows_required: 2
    21 Alumni: where rn<=>
    21 news: where rn<=>

    EMP_ID EMP_NA
    ---------- ------
    1 name 1
    1 name 3
    2 name 2
    2 name 4

  • Need to rotate the sub query using 11 g

    Hello

    Please find the below query

    SELECT AGING_BUCKET_ID, DAYS_START, DAYS_TO, AR_AGING_BUCKET_LINES TYPE
    WHERE AGING_BUCKET_ID = 3

    It displays the data as below

    AGING_BUCKET_ID DAYS_START DAYS_TO TYPE

    3-9999 0 CURRENT
    3 1 30 LAST
    3 31 60 LAST
    3 61 90 LAST
    3 91 9999999 PAST


    I tried to rotate the data, tried to make use of the PIVOT of the 11 g used the following query function

    WITH AGBUCK AS
    (
    SELECT AGING_BUCKET_ID, DAYS_START, DAYS_TO, AR_AGING_BUCKET_LINES TYPE
    WHERE AGING_BUCKET_ID = 3
    ) SELECT * FROM AGBUCK
    PIVOT)
    DAYS_START s1, s2 DAYS_TO, type
    FOR AGING_BUCKET_ID
    (3)
    );

    finished in the msg below:-ora-56902: wait for the aggregate within the operation of pivot function

    can you please help me to fix it.

    Concerning
    Yram

    Hi, Yram,

    Whenever you have a problem, after a few sample data and outcomes from these data.
    Sorry, I can't make a good guess at what you want, and I'm not an Oracle 11 database now to test. I think you want something like this:

    WITH      AGBUCK      AS
    (
         SELECT      AGING_BUCKET_ID
         ,     DAYS_START
         ,     DAYS_TO || TYPE      AS label
         FROM      AR_AGING_BUCKET_LINES
         WHERE      AGING_BUCKET_ID     = 3
    )
    SELECT     *
    FROM     agbuck
    PIVOT     (     MIN (days_start)
         FOR     label
         IN     (     '0 CURRENT'     AS current_0
              ,     '30 PAST'     AS past_30
              ,     '60 PAST'     AS past_60
              ,     '90 PAST'     AS past_90
              ,     '9999999 PAST'     AS past_9999999
              )
         )
    ;
    

    The first thing inside the parentheses after the PIVOT keyword must be an aggregate function. If there is a one-to-one correspondence between the lines in the "input" table and cells in the output, so no matter if you use the MIN or MAX (or, in the case of numbers, AVG or SUM).

  • Update to the CC query

    Hi all

    Quick question, I bought an flea market in Fireworks CS3 copy earlier and I wonder if I can use it to qualify for the discount of 1 year on the full package of CC?  I can't find a list of eligible programs, it just says: programs of CS3 or higher.

    Thank you

    Ian

    Hi Ian,

    I would like to inform you that if Fireworks CS3 serial number is registered under your Adobe account you are eligible for the discount of 1 year on the full package of CC.

    Thank you!

    Florianne

  • update to column values (false) in a copy of the same table with the correct values

    Database is 10gr 2 - had a situation last night where someone changed inadvertently values of column on a couple of hundred thousand records with an incorrect value first thing in the morning and never let me know later in the day. My undo retention was not large enough to create a copy of the table as it was 7 hours comes back with a "insert in table_2 select * from table_1 to timestamp...» "query, so I restored the backup previous nights to another machine and it picked up at 07:00 (just before the hour, he made the change), created a dblink since the production database and created a copy of the table of the restored database.

    My first thought was to simply update the table of production with the correct values of the correct copy, using something like this:


    Update mnt.workorders
    Set approvalstat = (select b.approvalstat
    mnt.workorders a, mnt.workorders_copy b
    where a.workordersoi = b.workordersoi)
    where exists (select *)
    mnt.workorders a, mnt.workorders_copy b
    where a.workordersoi = b.workordersoi)

    It wasn't the exact syntax, but you get the idea, I wanted to put the incorrect values in x columns in the tables of production with the correct values of the copy of the table of the restored backup. Anyway, it was (or seem to) works, but I look at the process through OEM it was estimated 100 + hours with full table scans, so I killed him. I found myself just inserting (copy) the lines added to the production since the table copy by doing a select statement of the production table where < col_with_datestamp > is > = 07:00, truncate the table of production, then re insert the rows from now to correct the copy.

    Do a post-mortem today, I replay the scenario on the copy that I restored, trying to figure out a cleaner, a quicker way to do it, if the need arise again. I went and randomly changed some values in a column number (called "comappstat") in a copy of the table of production, and then thought that I would try the following resets the values of the correct table:

    Update (select a.comappstat, b.comappstat
    mnt.workorders a, mnt.workorders_copy b
    where a.workordersoi = b.workordersoi - this is a PK column
    and a.comappstat! = b.comappstat)
    Set b.comappstat = a.comappstat

    Although I thought that the syntax is correct, I get an "ORA-00904: 'A'. '. ' COMAPPSTAT': invalid identifier ' to run this, I was trying to guess where the syntax was wrong here, then thought that perhaps having the subquery returns a single line would be cleaner and faster anyway, so I gave up on that and instead tried this:

    Update mnt.workorders_copy
    Set comappstat = (select distinct)
    a.comappstat
    mnt.workorders a, mnt.workorders_copy b
    where a.workordersoi = b.workordersoi
    and a.comappstat! = b.comappstat)
    where a.comappstat! = b.comappstat
    and a.workordersoi = b.workordersoi

    The subquery executed on its own returns a single value 9, which is the correct value of the column in the table of the prod, and I want to replace the incorrect a '12' (I've updated the copy to change the value of the column comappstat to 12 everywhere where it was 9) However when I run the query again I get this error :

    ERROR on line 8:
    ORA-00904: "B". "" WORKORDERSOI ": invalid identifier

    First of all, I don't see why the update statement does not work (it's probably obvious, but I'm not)

    Secondly, it is the best approach for updating a column (or columns) that are incorrect, with the columns in the same table which are correct, or is there a better way?

    I would sooner update the table rather than delete or truncate then re insert, as it was a trigger for insert/update I had to disable it on the notice re and truncate the table unusable a demand so I was re insert.

    Thank you

    Hello

    First of all, after post 79, you need to know how to format your code.

    Your last request reads as follows:

    UPDATE
      mnt.workorders_copy
    SET
      comappstat =
      (
        SELECT DISTINCT
          a.comappstat
        FROM
          mnt.workorders a
        , mnt.workorders_copy b
        WHERE
          a.workordersoi    = b.workordersoi
          AND a.comappstat != b.comappstat
      )
    WHERE
      a.comappstat      != b.comappstat
      AND a.workordersoi = b.workordersoi
    

    This will not work for several reasons:
    The sub query allows you to define a and b and outside the breakets you can't refer to a or b.
    There is no link between the mnt.workorders_copy and the the update and the request of void.

    If you do this you should have something like this:

    UPDATE
      mnt.workorders     A      -- THIS IS THE TABLE YOU WANT TO UPDATE
    SET
      A.comappstat =
      (
        SELECT
          B.comappstat
        FROM
          mnt.workorders_copy B   -- THIS IS THE TABLE WITH THE CORRECT (OLD) VALUES
        WHERE
          a.workordersoi    = b.workordersoi      -- THIS MUST BE THE KEY
          AND a.comappstat != b.comappstat
      )
    WHERE
      EXISTS
      (
        SELECT
          B.comappstat
        FROM
          mnt.workorders_copy B
        WHERE
          a.workordersoi    = b.workordersoi      -- THIS MUST BE THE KEY
          AND a.comappstat != b.comappstat
      )
    

    Speed is not so good that you run the query to sub for each row in mnt.workorders
    Note it is condition in where. You need other wise, you will update the unchanged to null values.

    I wouold do it like this:

    UPDATE
      (
        SELECT
          A.workordersoi
          ,A.comappstat
          ,B.comappstat           comappstat_OLD
    
        FROM
          mnt.workorders        A      -- THIS IS THE TABLE YOU WANT TO UPDATE
          ,mnt.workorders_copy  B      -- THIS IS THE TABLE WITH THE CORRECT (OLD) VALUES
    
        WHERE
          a.workordersoi    = b.workordersoi      -- THIS MUST BE THE KEY
          AND a.comappstat != b.comappstat
      ) C
    
    SET
      C.comappstat = comappstat_OLD
    ;
    

    This way you can test the subquery first and know exectly what will be updated.
    This was not a sub query that is executed for each line preformance should be better.

    Kind regards

    Peter

  • Update on the table by extracting the data from the table even under certain conditions

    Hi Experts,

    I have the table EMP which currently has 6 entries.

    EMP_SYS BATCH_NO JOIN_DATE LOGIN_ID STATUS FLAG

    1 FEBRUARY 10 PROD 84 Y IND123 ABC

    DEV 1-23 APRIL 98 Y IND123 ABC

    2 12 APRIL PROD 98 Y IND123 ABC

    2 2 APRIL DEV 98 Y IND123 ABC

    3 13 APRIL PROD 98 Y IND123 ABC

    3 3 APRIL DEV 98 Y IND123 ABC

    CONDITION: I need to take lines which has the minimum BATCH_NO for each of the EMP_SYS

    for example,.

    1 FEBRUARY 10 PROD 84 Y IND123 ABC

    DEV 1-23 APRIL 98 Y IND123 ABC

    For the above two lines, I need to update the status of DEF. How to select this criterion and update in the same query?

    Currently, I used the query to select the minimum BATCH_NO for each of the EMP_SYS below.

    SELECT EMP_SYS, BATCH_NO, JOIN_DATE, FLAG, LOGIN_ID, STATUS

    Of

    (

    EMP_SYS, BATCH_NO, JOIN_DATE, FLAG, LOGIN_ID, STATUS, SELECT ROW_NUMBER)

    COURSE NR (PARTITION BY ORDER OF EMP_SYS OF EMP_SYS)

    FROM EMP

    WHEN STATUS = 'ABC' AND FLAG = "Y".

    )

    WHERE

    NR = 1;

    If I try to use the update on the above query statement... It updates every 6 rows instead of 2 rows.

    Please suggest me a way to update only the two lines that has the minimum BATCH_NO for each of the EMP_SYS.

    But is possible to write the query without using the Group of?

    Update e EMP

    set STATUS = "DEF".

    where BATCH_NO = (select min (BATCH_NO) from EMP I where STATUS = 'ABC' AND FLAG = 'Y' and i.emp_sys = e.emp_sys)

  • Re: update of the lines double

    Oracle 11.2.0.2
    Windows 2008

    I have this table (case_file) with lines double (case_number).
    I want to make the unique case_number across the table.

    For example, if I have two lines with the same case_number (225), I would change one of the numbers and record this case_number to the privious_case_number column.

    I'm looking for a way to write a script to automate the process.
    Any help will be appreciated.
    CREATE sequences case_id_seq
    start with 25;

    create the table case_file
    (case_id number not null, case_number varchar2 (25), privious_case_number varchar (25), modified_by varchar2 (50));
    INSERT into case_file (case_number, privious_case_number, case_id, modified_by)
    VALUES (case_id_seq.nextval, ' 220 ', ' 2002', "S/n");
    INSERT into case_file (case_number, privious_case_number, case_id, modified_by)
    VALUES (case_id_seq.nextval, '225', null, "S/n");
    INSERT into case_file (case_number, privious_case_number, case_id, modified_by)
    VALUES (case_id_seq.nextval, '224', null, 'PM');
    INSERT into case_file (case_number, privious_case_number, case_id, modified_by)
    VALUES (case_id_seq.nextval, '205', null, 'Controller');
    INSERT into case_file (case_number, privious_case_number, case_id, modified_by)
    VALUES (case_id_seq.nextval, '225', null, "S/n");
    When I run the sub query, I get this result, with 225 appear twice:
    Select * from case_file;

    26/2002 225 S/N
    27 220 2002 S/N
    28 DBA 225
    29 224 H
    30 205 supervisor
    31 DBA 225
    when I run the below script:
    SELECT case_number, COUNT (case_number) as Number_Of_Case_Number
    OF case_file
    GROUP BY case_number
    HAVING COUNT (case_number) 1 >
    I get this result
    CASE_NUMBER NUMBER_OF_CASE_NUMBER
    ------------------------- ---------------------
    3 225

    SQL >
    edited by: 868332 on 6 February 2012 13:23

    Hello

    Do you really need two unique numbers for each line?

    That unique case_numebr, first, see what the highest existing case_number and create a new sequence that begins after this point:

    CREATE SEQUENCE     case_number_seq
    START WITH     250;
    

    Always use this sequence when you set case_numbers in the future.

    Re - number existing duplicates:

    UPDATE     case_file
    SET     case_number          = case_number_seq.NEXTVAL
    ,     previous_case_number     = case_number
    WHERE     case_id         IN (
                         WITH  got_r_num     AS
                      (
                          SELECT  case_id
                          ,       ROW_NUMBER () OVER ( PARTITION BY  case_number
                                                              ORDER BY         case_id
                                         )  AS r_num
                          FROM    case_file
                      )
                      SELECT  case_id
                      FROM        got_r_num
                      WHERE   r_num     > 1
                     )
    ;
    

    The subquery got_r_num assigns numbers 1, 2, 3,... for all lines, in the order of case_id (the lowest case_id gets r_num = 1) with a separate set of kinds for each case_number. When there are duplicates, one of the lines with this case_number will keep this case_number, and all others will again be case_numebr_seq case_numebrs.

    Published by: Frank Kulash on 6 February 2012 16:37
    Initially missed the part about previous_case_number. (Make sure the "previous" spelling.)

  • Problem with the simple query.

    Hi all

    I am facing problem with the query below

    Select A.COL1, A.COL2

    B.COL1, B.COL2

    FROM TABLE1 A

    TABLE 1 B

    WHERE A.header = '123'

    AND B.header = '123'

    AND nvl (A.COL6, 'ABC') = 'ABC '.

    AND NVL (B.COL6, 'DEF') = 'DEF '.

    Basically, my requiremenyt is: I have only one table, TABLE1 here, which has a line two lines (for the same header) as "ABC" and another is "DEF". Table 1 has two columns (col1, col2) that should be displayed for both lines.

    When the header has two records in table1 top query works. and but if I do not have a record for any header example there are a record for "abc" in col6 only. so my query above does not work because there is no record for 'DEF' in col6. But I want to again request to fecth the output (for b.col1 and b.col2 should have null values)

    could you pls suggest me how to get the 4 columns.

    Thanks in advance

    Kind regards

    UVA.

    Try to place the status of outer join on column: analytical_criterion_code as

    and nvl (AUDIT.analytical_criterion_code, 'AUDIT2') = 'verification2. '

    .

    .

    and nvl (TRANS.analytical_criterion_code, 'TRANS2') = 'TRANS2.

    In the sub query based on the opinions that you have given in post # 1, although there is no value "DEF * ' for col6 due to the condition of outer join on b.col6 (+) line is extracted with b.col [1,2,3] as NULL values. Try to remove the (+) sign b.col6 and test.

    with t as)

    Select 111 col1, col2 'aaa', 'ABC' col6 123 header of all the double union

    Select 222 'bbb', 'DEF' col6, 123 double header

    )

    q as (select 123 double header)

    Select A.COL1, A.COL2, A.COL6

    B.COL1, B.COL2, b.COL6

    q.header

    T a

    t b

    q

    where a.col6 (+) = 'ABC '.

    and b.col6 (+) = "DEF."

    and q.header = a.header (+)

    and q.header = b.header (+)

  • Need to use values from the first query in other queris to the data model

    Hello
    Here is my requirement-

    I use the data model to run multiple queries. The first query, I get 10 records. Now, I want to use these 10 records in the second query to get my final result. I am not able to use the sub query as the two motions are quite long and complex.

    Select distinct Bishop of emp

    Select empno, emp where Bishop in (: Bishop)

    I can't use: Bishop because it will give only the last value stored at Archbishop. Is it possible to be able to use all the values from the first query in the second query using the data model?

    Hello

    Are you sure that you have your "dataStructure" configured correctly? Try this simple example:

                                                                          
    

    Hope this helps

    Andy

  • Problems with Sub query

    Hello, I'm looking to create a sub query to display certain information. On the form that the information is entered, the user has the option to enter a phone number extension, as appropriate. If this is the case, I want the phone number to show as 555-867-5309 (x 1234). However, without the problem of controls, the (x) will be displayed without worrying and seems sloppy. Here is the code I have, please notify.

    There will be two places, it will be necessary - for the telephone number of the applicant and the app (SME) contact information manager.

    Thank you.

    select
        pm.pk_proj_master_id "Project Number",
        pm.trackit_work_order "TrackIt Work Order",
        pm.name "Project Name",
        pm.status "Project Status",
        req.last_name||', '||req.first_name||', '||req.middle_initial||'.' "Requestor Name",
        rde.department_group_descr "Requestor Department Name",
        req.department_descr "Requestor Division Name",
        
        pm.requester_ext,
        case
            when pm.requester_ext in 
                (
                select 
                    pm.requester_phone|| '(x'||pm.requester_ext ||')' "Requesters Number"
                from 
                    protrac_master pm
                where
                    pm.requester_ext is not null
                )
            
            else
                (
                select
                    pm.requester_phone "Requesters Number"
                from 
                    protrac_master pm
                )   
        end as "Requester Number",
         
        man.last_name||', '||man.first_name||', '||man.middle_initial||'.' "SME Name",
        mdg.department_group_descr "SME Department Name",
        man.department_descr "SME Division Name",
        
        pm.app_manager_ext,
        case
            when pm.app_manager_ext in 
                (
                select 
                    pm.app_manager_phone|| '(x'||pm.app_manager_ext ||')' "SME Number"
                from 
                    protrac_master pm
                where
                    pm.app_manager_phone is not null
                )
            
            else
                (
                select
                    pm.app_manager_phone "SME Number"
                from 
                    protrac_master pm
                )   
        end as "Requester Number",
    
        pm.createby_date "Date Entered",
        pm.date_begin "Date Began",
        pm.date_completed "Date Completed",
        pm.estimated_date "Estimated Completion Date"
    
    from
        protrac_master pm,
        cobr.vw_pps_payroll req, cobr.department_group rde,
        cobr.vw_pps_payroll man, cobr.department_group mdg
        
    where
        pm.requester_id         = req.emple_no and
        pm.requester_dept_id    = rde.pk_department_group_id and
        pm.app_manager_id       = man.emple_no and 
        pm.app_manager_dept_id  = mdg.pk_department_group_id
        
    order by 
        pm.pk_proj_master_id

    I think you can avoid the sub query thing simply by using the NVL2 function:

    select ...
         , NVL2( pm.requester_ext
               , pm.requester_phone|| '(x'||pm.requester_ext ||')'
               , pm.requester_phone) "Requesters Number"
           ...
         , NVL2( pm.app_manager_ext
               , pm.app_manager_phone|| '(x'||pm.app_manager_ext ||')'
               , pm.app_manager_phone) "Manager Number"
           ...
      from protrac_master pm
         , ...
    
  • Update the same column in the same table

    Hello

    How do update you a records of column in the same table?

    I have purchase_order of the table. Consists of column ID, color, Purchase_No, Sub purchase.


    < pre >

    Create table Purchase_Order)
    Identification number,
    color varchar2 (10),
    purchase_No varchar2 (5).
    purchase_sub varchar2 (2));
    < / pre >

    < pre >

    ID color Purchase_No purchase Sub
    6416 S1406 PURPLE 3
    6415 S1406 GREEN 2
    6414 S1406 GREEN 1
    6419 S1406 3
    6417 S1406 1
    6418 S1406 2

    < pre >

    6 unique ID records is in the same site. But 2 ID will be confined to a purchase_sub.

    For example

    6416,6419 purchase_no S1406 but has the same purchase_sub who need 3.I 6419 color "Purple".

    Expected results:
    < pre >

    ID color Purchase_No purchase Sub
    6416 S1406 PURPLE 3
    6415 S1406 GREEN 2
    6414 S1406 GREEN 1
    6419 S1406 PURPLE 3
    6417 S1406 GREEN 1
    6418 S1406 GREEN 2

    < / pre >

    Thank you!

    Published by: CrackerJack on May 4, 2009 15:04

    Hello

    Try this,

    UPDATE Purchase_Order a
       SET a.Colour = (SELECT colour
                         FROM Purchase_Order b
                        WHERE a.Purchase_Sub = b.Purchase_Sub
                          AND b.colour Is Not Null)
     WHERE a.Colour Is Null
    

    Kind regards
    Christian Balz

  • Update of several rows of the same table using trigger

    Hello

    I have the following table

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

    CREATE TABLE ATT_PERMISSIONS
    (
    DATE OF PRMONTHYR,
    EMPIDNUMBER (10)DEFAULT VALUE 0,
    FROMDATETIMEDATE,
    TODMTFDATETIMEDATE,
    NUMBER OF PERMMINS (3),

    SSLINASTRETCH NUMBER (3).

    PERMATTINELIGIBLENUMBER (1)DEFAULT VALUE 0
    );

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

    I want to update the column PERMATTINELIGIBLE in the same table when each line is inserted.

    I created following trigger for that

    CREATE OR REPLACE TRIGGER SSL_AFTER_UPDATE AFTER UPDATE ON ATT_PERMISSIONS

    FOR EACH LINE

    BEGIN

    Update ATT_PERMISSIONS set PERMATTINELIGIBLE =

    (

    SELECT THE CHECK BOX

    WHEN PERMMINS < = 60

    or

    (

    PERMMINS < = SSLINASTRETCH

    AND

    COUNT (CASE WHEN PERMMINS = 0 THEN NULL OTHERWISE 1 END)

    COURSES (PARTITION BY empid, prmonthyr) < = 1

    )

    THEN 1

    0 OTHERWISE

    END

    FROM ATT_PERMISSIONS where prmonthyr =:new.prmonthyr, empid =:new.empid

    ) where prmonthyr =:new.prmonthyr, empid =:new.empid;

    END;

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

    That is to say.

    When a row is inserted the PERMATTINELIGIBLE of all records for this employee for the month is recalculated.

    There would be only two or three records for an employee for a month.

    PERMMINS is the number of minutes to use as short leave.

    If it is less than 60 is eligible for the bonus to attendance for this employee.

    If this isn't normally the date is not eligible for the attendance for this employee premium.

    but an exception is that if a short leaves of DISP employee allowed a month (IE. ( SSLINASTRETCH ) in a straight line, IE. one day, that day is eligible for the bonus of presence.

    That is to say. Why the number of short leaves in a month is taken. If it's one and done minutes use is lower to SSLINASTRETCH, then the day is eligible for the attendance bonus.

    But when I try to create the trigger I get error, PL/SQL: ORA-00907: missing a right parenthesis.

    Help, please

    I use oracle 10g

    I want to update the column PERMATTINELIGIBLE in the same table, when each row is inserted.

    No - you do NOT want to do in a trigger.

    You cannot query the same table that the trigger is activated on. -C' is a MUTANT and you will get an exception.

    When a row is inserted is recalculated to the PERMATTINELIGIBLE of all the records for that employee for that month.

    There would be only two or three records for an employee for a month.

    PERMMINS is the number of minutes to use as short leave.

    If it is less than 60 is eligible for the bonus to attendance for this employee.

    If is not normally the day is not eligible for the premium of attendance for this employee.

    but an exception is that if a short leaves of DISP employee allowed a month (IE. SSLINASTRETCH) in a straight line, IE. one day, that day is eligible for the bonus of presence.

    That is to say. Why the number of short leaves in a month is taken. If it's one and done minutes use is less than SSLINASTRETCH, then the day is eligible for the bonus of presence.

    But when I try to create the trigger I get error, PL/SQL: ORA-00907: missing a right parenthesis.

    You can not do in a trigger. Even if correct you this error of syntax, you will get the exception that I mentioned above.

    Oracle is a multi-user system. Other users can modify the same table that you use.

    So even if you could try to interview "all the records for this employee" some of them may be locked if other users access them. Also, an insert statement could try to insert two rows for an employee and the trigger could not have seen the other lines still.

    If you want to work with data SETS (all records for an employee), you must write the PL/SQL code that LOCKS all lines updated to prevent others to interfere.

    Then you make your operations but NOT in a trigger. Perform inserts and then use an UPDATE query to set this value.

    Then VALIDATE to unlock the lines.

  • Updated with the values in the same table, for other records corresponding to conditions

    Hi Experts,

    Sorry do not provide the structure of the table (it is a simple structure)

    I have a requirement where I need to update the columns of a table based on the same table with some match empid and date values. If the date and empid match so I have these values to any other folder and update of one who is not having details of Office . I need the Update query

    Before the update my array of values is as below

    Sort_num Emp_id Bureau start_date

    1 101 AUS 01/01/2013
    2 101 01/01/2013
    3 101 15/01/2013
    4 103 USA 01/05/2013
    5 103 01/01/2013
    6 103 05/01/2013
    7 104 FRA 01/10/2013
    8 104 10/01/2013
    9 104 01/01/2013

    After update my table should be as below

    Sort_num Emp_id Bureau start_date

    1 101 AUS 01/01/2013
    2 101 AUS 01/01/2013
    3 101 15/01/2013
    4 103 USA 01/05/2013
    5 103 01/01/2013
    6 103 USA 01/05/2013
    7 104 FRA 01/10/2013
    8 104 FRA 01/10/2013
    9 104 01/01/2013

    Thanks in advance

    I don't have the time to create the table with the data, but basically, you should be able to code the following text

    update one table

    Office set = (select desktop in table b where b.emp_id = a.emp_id)

    and b.start_date = a.start_date

    and b.office is not null

    )

    where is ([as well as overall query])

    and a.office is null

    In my opinion, who will do the trick.

    HTH - Mark D Powell.

  • How to update columns with the value of other lines in the same table

    Hello

    I use Oracle 11.2, I'd use SQL statements to update a column based on values in other rows in the same table. Here are the details:

    create table TB_test (number 4 myId, crtTs date, date of MDPU);

    insert into tb_test (1, to_date ('20110101', 'YYYYMMDD'), null);
    insert into tb_test (1, to_date ('20110201', 'YYYYMMDD'), null);
    insert into tb_test (1, to_date ('20110301', 'YYYYMMDD'), null);
    insert into tb_test (2, to_date ('20110901', 'YYYYMMDD'), null);
    insert into tb_test (2, to_date ('20110902', 'YYYYMMDD'), null);

    After you run the SQL code, I would like to have the following result:

    1, 20110101, 20110201
    1, 20110201, 20110301
    1, 20110301, null
    2, 20110901, 20110902
    2, 20110902, null

    Thanks for your suggestion.

    I guess you need this, otherwise please explain logic correctly:

    SQL> merge into tb_test t
      2  using (
      3    select rowid as rid
      4         , lead(crtts) over(partition by myid order by crtts) as updts
      5    from tb_test
      6  ) v
      7  on (t.rowid = v.rid)
      8  when matched then update
      9   set t.updts = v.updts
     10  ;
    
    5 rows merged.
    
    SQL> select * from tb_test order by 1,2;
    
          MYID CRTTS     UPDTS
    ---------- --------- ---------
             1 01-JAN-11 01-FEB-11
             1 01-FEB-11 01-MAR-11
             1 01-MAR-11
             2 01-SEP-11 02-SEP-11
             2 02-SEP-11
    

Maybe you are looking for