Case Statement in Oracle Query.

Hello Oracle Gurus,
I need suggestion on whether I should use Case statement in Oracle queries.
I have a sql statement which inserts the data by selecting data from other table. While selecting the data I have put a logic in the select statement for one column which is something like this and there are some more similar statements in the same query.
CASE
               WHEN (b.ACCOUNT = 'FIN' or b.ACCOUNT ='FIN ACC' or b.ACCOUNT like '%Global Eq%' or b.ACCOUNT like '%Flexible Bond%')
               THEN
                    'MTM'
                         WHEN (substr(a.CTC,-3)='MTM')
               THEN
                    'MTM'
                         WHEN (substr(a.CTC,-3)='AFS' or substr(a.CTC,-3)='HTM' OR substr(a.CTC,-3)='ACC' OR substr(a.CTC,-3)='HFI' )
               THEN
                    'ACC'
               ELSE
                              'OTH'
          END,
I wanted to get an suggestion about how much performance issue can I have due to this in my insert statement.
Let me know if you need any other information.All comments are really appreciated.

Hi,
It's depends on the joins how you have performed with source table, stats and existing of indexes. If the volume of data is high - in case of any performance issue - why can't you perform the required things of logical conditions of data and popualte in one cluster so - that you can fetch out the chunks of required information with better way and in support with indexes.
Let us know the ful query your working on
Oracle version
Explain plans - get it from dbms_xplan.
- Pavan Kumar N
- ORACLE - 9i/10g - OCP
RHCE - Enterprize Linux 5.4

Similar Messages

  • Case Statement in sub query

    Hi, I have two issues, here is my initial code:
    select
    cc.name_id_no
    ,cc.discover_date
    ,cc.cla_case_no
    ,max(rl.year_of_incident)Non_Loss_Past_5
    ,rl.timestamp
    from cla_case cc, rbn_loss rl
    where cc.name_id_no = rl.customer_no
    and rl.year_of_incident < trunc(cc.discover_date)
    and rl.type_of_loss < 1000
    and rl.timestamp < trunc(cc.discover_date)
    and (cc.question_class = 20
    or cc.question_class = 25)
    and (trunc(cc.discover_date)- (rl.year_of_incident)) < 1095
    --and (trunc(cc.discover_date) <> (rl.year_of_incident))
    group by cc.cla_case_no,name_id_no, cc.discover_date,rl.timestamp
    Now a cla_case_no can map to several year_of_incident. I only want the cla_case_no that maps to the max year_of_incident ie There should only be a single cla_case_no corresponding to the max year_of_incident.
    To get around this I did the following which is not very efficient and I'm hoping it can be improved:
    select distinct z.cla_case_no from (
    select
    cc.name_id_no
    ,cc.discover_date
    ,cc.cla_case_no
    ,max(rl.year_of_incident)Non_MW_Loss_Past_5
    ,rl.timestamp
    from cla_case cc, rbn_loss rl
    where cc.name_id_no = rl.customer_no
    and rl.year_of_incident < trunc(cc.discover_date)
    and rl.type_of_loss < 1000
    and rl.timestamp < trunc(cc.discover_date)
    and (cc.question_class = 20
    or cc.question_class = 25)
    and (trunc(cc.discover_date)- (rl.year_of_incident)) < 1095
    --and (trunc(cc.discover_date) <> (rl.year_of_incident))
    group by cc.cla_case_no,name_id_no, cc.discover_date,rl.timestamp
    ) z
    Now comes the second issue: The above is actually a subquery that will link to a bigger table via cla_case_no ccx
    SELECT
    ie ,(select distinct z.cla_case_no from (
    select cc.name_id_no, cc.discover_date ,cc.cla_case_no, max(rl.year_of_incident)Non_MW_Loss_Past_5, rl.timestamp
    from cla_case cc, rbn_loss rl
    where cc.name_id_no = rl.customer_no
    and rl.year_of_incident < trunc(cc.discover_date)
    and rl.type_of_loss < 1000
    and rl.timestamp < trunc(cc.discover_date)
    and (cc.question_class = 20
    or cc.question_class = 25)
    and (trunc(cc.discover_date)- (rl.year_of_incident)) < 1095
    --and (trunc(cc.discover_date) <> (rl.year_of_incident))
    group by cc.cla_case_no,name_id_no, cc.discover_date,rl.timestamp
    ) z
    where z.cla_case_no = ccx.cla_case_no
    ) Non_MW_Loss_Past_5
    FROM etc
    Now only certain cc.cla_case_no from the subquery will corresp to the ccx_cla_case_no from the main table and the other entries will be null.
    What I require is that if the subquery returns a result that IS NOT NULL to return 'Y' ELSE 'N' instead of the varies cla_case_no's and (null) entries in the Non_MW_Loss_Past_5 column
    Thanks!!!
    Banner:
    Oracle Database 11g Release 11.2.0.2.0 - 64bit Production
    PL/SQL Release 11.2.0.2.0 - Production
    "CORE 11.2.0.2.0 Production"
    TNS for Linux: Version 11.2.0.2.0 - Production
    NLSRTL Version 11.2.0.2.0 - Production

    Hi,
    It looks like you have another copy of this question:
    Case Statement and sub query
    That's probably not your fault, but you should mark the other copy as "Answered" right away, and then you'll only have to look for replies in one place.
    885178 wrote:
    ... Now a cla_case_no can map to several year_of_incident. I only want the cla_case_no that maps to the max year_of_incident ie There should only be a single cla_case_no corresponding to the max year_of_incident.If you know there will only be one, then you can use LAST, and you don't need GrOUP BY
    To get around this I did the following which is not very efficient and I'm hoping it can be improved:
    select distinct z.cla_case_no from (
    select
    cc.name_id_no
    ,cc.discover_date
    ,cc.cla_case_no
    ,max(rl.year_of_incident)Non_MW_Loss_Past_5
    ,rl.timestamp
    from cla_case cc, rbn_loss rl
    where cc.name_id_no = rl.customer_no
    and rl.year_of_incident < trunc(cc.discover_date)
    and rl.type_of_loss < 1000
    and rl.timestamp < trunc(cc.discover_date)
    and (cc.question_class = 20
    or cc.question_class = 25)
    and (trunc(cc.discover_date)- (rl.year_of_incident)) < 1095
    --and (trunc(cc.discover_date) <> (rl.year_of_incident))
    group by cc.cla_case_no,name_id_no, cc.discover_date,rl.timestamp
    ) zHere's one way:
    SELECT       MIN (cla_case_no) KEEP (DENSE_RANK LAST ORDER BY r1.year_of_incident)
                         AS latest_cla_case_no
    FROM       cla_case     cc
    ,             rbn_loss      rl
    WHERE     cc.name_id_no          = rl.customer_no
    AND       rl.year_of_incident     > TRUNC (cc.discover_date) - 1095
    AND       rl.year_of_incident      < TRUNC (cc.discover_date)
    AND       rl.type_of_loss     < 1000
    AND       rl.timestamp          < TRUNC (cc.discover_date)
    AND       cc.question_class     IN (20, 25)
    ;If you'd post some sample data (CREATE TABLE and INSERT statements) and the results you want from that data, then I could test this.
    Now comes the second issue: The above is actually a subquery that will link to a bigger table via cla_case_no ccx
    SELECT
    ie ,(select distinct z.cla_case_no from (
    select cc.name_id_no, cc.discover_date ,cc.cla_case_no, max(rl.year_of_incident)Non_MW_Loss_Past_5, rl.timestamp
    from cla_case cc, rbn_loss rl
    where cc.name_id_no = rl.customer_no
    and rl.year_of_incident < trunc(cc.discover_date)
    and rl.type_of_loss < 1000
    and rl.timestamp < trunc(cc.discover_date)
    and (cc.question_class = 20
    or cc.question_class = 25)
    and (trunc(cc.discover_date)- (rl.year_of_incident)) < 1095
    --and (trunc(cc.discover_date) <> (rl.year_of_incident))
    group by cc.cla_case_no,name_id_no, cc.discover_date,rl.timestamp
    ) z
    where z.cla_case_no = ccx.cla_case_no
    ) Non_MW_Loss_Past_5
    FROM etc
    Now only certain cc.cla_case_no from the subquery will corresp to the ccx_cla_case_no from the main table and the other entries will be null.
    What I require is that if the subquery returns a result that IS NOT NULL to return 'Y' ELSE 'N' instead of the varies cla_case_no's and (null) entries in the Non_MW_Loss_Past_5 column
    NVL2 (x, 'Y', 'N')returns 'Y' if x is NULL, and it returns 'N' if x is not NULL. X can be a scalar sub-query:
    NVL2 ((SELECT ...), 'Y', 'N')You could also use an EXISTS sub-query:
    CASE
        WHEN  EXISTS (SELECT ...)
        THEN  'Y'
        ELSE  'N'
    END

  • CASE statement in Oracle 8i PL/SQL

    I'm in the process of doing an upgrade from 8i to 10g and have the necessary instructions in performing it. however, after running the pre upgrade tasks (run utlu102i.sql) to show the preupgrade information, i found out that there are some INVALID objects.
    Miscellaneous Warnings
    WARNING: --> Database contains INVALID objects prior to upgrade.
    .... USER INGITRN has 1 INVALID objects.
    .... USER INGIUAT has 3 INVALID objects.
    .... USER OEMMON has 7 INVALID objects.
    .... USER RE_ITF_USER has 11 INVALID objects.
    .... USER SYS has 1 INVALID objects.
    Would it be ok to proceed with the upgrade and ignore the warnings?
    Also, as i checked the invalid object for SYS, it shows:
    OWNER OBJECT_NAME OBJECT_TYPE STATUS
    SYS UTL_RECOMP PACKAGE VALID
    SYS UTL_RECOMP PACKAGE BODY INVALID
    Further more, i tried to do a fix by invoking utlirp.sql and the same objects are showing up. Same thing shows when invoking utlrp.sql or even doing a manual compile for the affected objects. I later found out that CASE statements are not accepted in PL/SQL for Oracle 8i.
    Can you help me fixed the issue on the invalid object?
    Thanks

    Hi,
    Try first to (re)compile ll invalid objects. then
    you can run:
    select owner,type,count(*) from all_errors
    group by owner,typeif you still have uncompiled objects, then report the different errors:
    select * from all_errors...

  • Just a FYI regarding Case statements in ORacle 8i in pl/sql

    Well..I saw numerous posts in this forum regarding not being able to do case statement within pl/sql. Well..you can do
    that using dynamic SQL. IT works like a champ.

    Hi,
    Try first to (re)compile ll invalid objects. then
    you can run:
    select owner,type,count(*) from all_errors
    group by owner,typeif you still have uncompiled objects, then report the different errors:
    select * from all_errors...

  • Case statement in Oracle 8i

    can anyone tell me what to do to make the query below run in Oracle 8i.
    thanks
    select
    case connum
    when 'C251234' then 'Good'
    when 'C318260' then 'Ok'
    else connum end
    from names

    I believe the confusion arises since CASE and other new functions and features in 8i - analytic functions, NVL2 scalar subquery ..., did not work in PL/SQL in 8i due to it having a different SQL parsing engine. A common work around was to put the offending SQL in a view or execute it as dynamic SQL where PL/SQL would use the database parser.
    SQL> select
      2  case when connum = 'C251234' then 'Good'
      3  when connum = 'C318260' then 'Ok'
      4  else connum end
      5  from (
      6  select 'AAAA' connum from dual
      7  union all
      8  select 'C251234' from dual
      9  union all
    10  select 'C318260' from dual
    11  );
    CASEWHE
    AAAA
    Good
    Ok
    SQL> var c refcursor
    SQL> begin
      2  open :c for
      3  select
      4  case when connum = 'C251234' then 'Good'
      5  when connum = 'C318260' then 'Ok'
      6  else connum end
      7  from (
      8  select 'AAAA' connum from dual
      9  union all
    10  select 'C251234' from dual
    11  union all
    12  select 'C318260' from dual
    13  );
    14  end;
    15  /
    case when connum = 'C251234' then 'Good'
    ERROR at line 4:
    ORA-06550: line 4, column 1:
    PLS-00103: Encountered the symbol "CASE" when expecting one of the following:
    ( * - + all mod null <an identifier>
    <a double-quoted delimited-identifier> <a bind variable>
    table avg count current distinct max min prior sql stddev sum
    unique variance execute the forall time timestamp interval
    date <a string literal with character set specification>
    <a number> <a single-quoted SQL string>
    SQL> var c refcursor
    SQL> begin
      2  open :c for
      3  'select
      4  case when connum = ''C251234'' then ''Good''
      5  when connum = ''C318260'' then ''Ok''
      6  else connum end
      7  from (
      8  select ''AAAA'' connum from dual
      9  union all
    10  select ''C251234'' from dual
    11  union all
    12  select ''C318260'' from dual
    13  )';
    14  end;
    15  /
    PL/SQL procedure successfully completed.
    SQL> print c
    CASEWHE
    AAAA
    Good
    Ok
    SQL> select * from v$version where rownum = 1;
    BANNER
    Oracle8i Enterprise Edition Release 8.1.7.4.0 - Production

  • Got error when use case statement in oracle stored procedure

    Hi,
    I have a query like:
    select merchant_id,
    case
    when product_type='K' then 'Production'
    when product_carrier='UC' THEN 'Shipping'
    end the_type
    from product_tbl
    where merchant_id=10114
    It works fine. But as soon as I put it into a stored procedure, I got error like:
    Encountered the symbol "CASE" when expecting one of the following:
    ( - + mod null <an identifier>
    Please help!

    Oracle 8i doesn't support CASE into PL/SQL, so as Kamal said, create a view with the CASE, and use this view into your PL/SQL.
    Nicolas.
    And an example here :
    Re: Execute Immediate doesnot work in 8i (8.1.7) and Ref Cursor not exec qu
    Sorry Kamal.
    Message was edited by:
    N. Gasparotto

  • Need help converting Excel IF statement into CASE WHEN statement for Oracle

    Hi,
    Hope someone can help I have tried various ways of getting this to work, to no avail!
    Bascially I have some figures that are minus figures, and I need to add them together to get a movement figure, but I need to treat the minus figures as minus, if that makes sense, rather than the usual... a minus and a minus makes a plus.
    For example:- Budget Figure = -1% and Actual Figure = -68% so the movement needs to be -69%.
    The IF statement I have been using in Excel is the following:-
    =IF(FO110<0,(FP110-(IF(FO110=0,1,FO110)*-1)),FP110-IF(FO110=0,1,FO110))
    Which when using the figures as above = -69%
    Cell FO = The Budget Figure
    Cell FP = The Actual Figure
    However, when I created the CASE statement in Oracle, the figure in the query comes back as -0.67, which is oviously not what I want to happen when both actual and budget are minus figures; however when they are a minus and a plus, it works perfectly fine.
    Any help on this would be most appreciated!
    Kind regards,
    Annmarie

    Happy I did'n mess something up :)
    Nevertheless, don't show it too much around because
    case when budget < 0
         then actual - case when budget = 0  /* will never happen */
                            then 1           /* will never happen */
                            else budget
                       end * (-1)            /* -budget * (-1) remains only */
         else actual - case when budget = 0
                            then 1
                            else budget
                       end
    endso at least try the following (if case is more readable as decode for you). Let's hope it works as I don't have a Database at hand
    case when budget < 0
         then actual + budget
         else actual - case when budget = 0
                            then 1
                            else budget
                       end
    end Regards
    Etbin

  • SQL CASE statement in XML template- End tag does not match start tag 'group

    Hi All,
    I am developing a report that has the SQL CASE statement in the query. I am trying to load this into RTF with report wizard and it gives me below error
    oracle.xml.parser.v2.XMLParseException: End tag does not match start tag 'group'
    Does XML publisher support CASE statement?
    My query is something like this
    SELECT customercode,
    SUM(CASE WHEN invoicedate >= current date - 30 days
    THEN balanceforward ELSE 0 END) AS "0-30",
    SUM(CASE WHEN invoicedate BETWEEN current date - 60 days
    AND current date - 31 days
    THEN balanceforward ELSE 0 END) AS "31-60",
    SUM(CASE WHEN invoicedate < current date - 60 days
    THEN balanceforward ELSE 0 END) AS "61>",
    SUM(balanceforward) AS total_outstanding
    FROM MyTable
    GROUP BY customercode
    ORDER BY total_outstanding DESC
    Please advice if the CASE statement or the double quotes are causing this error
    Thanks,
    PP

    I got this to work in the XML but the data is returning zeros for all the case statements. When I run this in toad I get results for all the case conditions but when ran in XML the data displayed is all zeros. I am not sure what I am missing. Can someone shed some light on this please
    Thanks!
    PP

  • Max Case Statement

    Hi,
    Can anyone help with the case statement in the query below, is it possible to check the date using MIN in a case statement? The MIN date needs to be split by ID.
    SELECT id,
    name,
    MIN(to_date(payment_date, 'YYYYMMDD')) first_date,
    MAX(to_date(payment_date, 'YYYYMMDD')) last_date,
    CAST(SUM(payment_amount) AS DOUBLE PRECISION) amount,
    ABS(CAST(SUM(
    CASE
    WHEN payment_amount < 0 and to_date(payment_date, 'YYYYMMDD') > MIN(to_date(payment_date, 'YYYYMMDD')) THEN payment_amount
    END) AS DOUBLE PRECISION)) credit
    FROM test
    group by id, name
    ORA-00937: not a single-group group function
    00937. 00000 - "not a single-group group function"
    I am trying to acheive the following in the case statement:
    CASE
    WHEN payment_amount < 0 and payment_date > first_date THEN payment_amount
    END

    Hi,
    sliderrules wrote:
    Below is a test script:
    create table test(
    id number,
    name varchar2(10),
    payment_date date,Is payment_date a DATE or a string?
    As the name implies <b>TO_</b>DATE converts a string TO a DATE. If payment_date is already a DATE, there's no need to convert it.
    payment_amount number
    insert into test values(001, 'HK', '20-SEP-10', 69.36);If payment_date is a DATE, don't try to insert a string (such as '20-SEP-10') into that column. Use TO_DATE here, not in your query.
    insert into test values(001, 'HK', '23-SEP-10', 235);
    insert into test values(001, 'HK', '23-SEP-10', 589.36);
    insert into test values(001, 'HK', '14-OCT-10', -743);
    insert into test values(001, 'HK', '18-OCT-10', -39.68);
    insert into test values(002, 'DU', '18-JUL-11', -56.36);
    insert into test values(002, 'DU', '23-SEP-11', 48.96);
    insert into test values(002, 'DU', '14-NOV-11', -529.63);
    insert into test values(002, 'DU', '14-FEB-12', -15.23);
    insert into test values(002, 'DU', '14-FEB-12', 896.21);
    insert into test values(002, 'DU', '18-APR-12', -55.14);
    insert into test values(003, 'GS', '11-APR-10', 36.69);
    insert into test values(003, 'GS', '23-SEP-10', 47.96);
    insert into test values(003, 'GS', '14-FEB-11', 14.23);
    insert into test values(003, 'GS', '14-JAN-12', -19.23);
    insert into test values(003, 'GS', '16-FEB-12', -63.22);
    insert into test values(003, 'GS', '18-JUL-12', -78.52);
    Expected Results:
    ID- 001
    NAME- HK
    FIRST_DATE- 20-Sep-10
    LAST_DATE- 18-Oct-10
    AMOUNT- 111.04
    CREDIT AMOUNT- -782.68
    ID- 002
    NAME- DU
    FIRST_DATE- 18-Jul-11
    LAST_DATE- 18-Apr-12
    AMOUNT- 288.81
    CREDIT AMOUNT- -656.36Why do you want -656.36 above? Why not -600.00?
    ID- 003
    NAME- GS
    FIRST_DATE- 11-Apr-10
    LAST_DATE- 18-Jul-12
    AMOUNT- -62.09
    CREDIT AMOUNT- -160.97Do you really want the results unpivoted like that, or do you want them in a tabular format, like this?
            ID NAME       FIRST_DAT LAST_DATE     AMOUNT     CREDIT
             1 HK         20-SEP-10 18-OCT-10     111.04    -782.68
             2 DU         18-JUL-11 18-APR-12     288.81       -600
             3 GS         11-APR-10 18-JUL-12     -62.09    -160.97If you want the unpivoted output, your Oracle version is even more important.
    ABS always returns a positive number whether you pass it a positive or a negative number. If credit is to be less than 0, then don't use ABS.
    SELECT id,
    name,
    MIN(to_date(payment_date, 'YYYYMMDD')) first_date,
    MAX(to_date(payment_date, 'YYYYMMDD')) last_date,
    CAST(SUM(payment_amount) AS DOUBLE PRECISION) amount,
    ABS(CAST(SUM(
    CASE
    WHEN payment_amount < 0 and to_date(payment_date, 'YYYYMMDD') > MIN(to_date(payment_date, 'YYYYMMDD')) THEN payment_amount
    END) AS DOUBLE PRECISION)) credit
    FROM test
    group by id, name
    ORA-00937: not a single-group group function
    00937. 00000 - "not a single-group group function"That looks like the same query you started with.
    I am trying to acheive the following in the case statement:
    CASE
    WHEN payment_amount < 0 and payment_date > first_date THEN payment_amount
    ENDThen compute first_date in a sub-query, as I showed earlier.

  • Need help in this sql query to use Case Statement

    hi All,
    I have the below query -
    SELECT DISTINCT OFFC.PROV_ID
    ,OFFC.WK_DAY
    ,CASE
    WHEN OFFC.WK_DAY ='MONDAY' THEN 1
    WHEN OFFC.WK_DAY ='TUESDAY' THEN 2
    WHEN OFFC.WK_DAY ='WEDNESDAY' THEN 3
    WHEN OFFC.WK_DAY ='THURSDAY' THEN 4
    WHEN OFFC.WK_DAY ='FRIDAY' THEN 5
    WHEN OFFC.WK_DAY ='SATURDAY' THEN 6
    WHEN OFFC.WK_DAY ='SUNDAY' THEN 7
    END AS DOW
    ,OFFC.OFFC_OPENG_TIME
    ,OFFC.OFFC_CLSNG_TIME
    FROM GGDD.PROV_OFFC_HR OFFC
    WHERE OFFC.PROV_ID='0000600'
    WITH UR;
    this query is bringing results in 6 differnt rows with opening and closing time for each day separately. I want to generate the data in one row with each day having opening and closing time, so for 7 days, total 14 columns with opening and closing time. But i am not able to do that using case statement.
    can somebody help me in achieving that.
    thanks,
    iamhere

    Hi,
    Welcome to the forum!
    That's called a Pivot .
    Instead of having 1CASE expression, have 14, one for the opening and one for the closing time each day, and do GROUP BY to combine them onto one row.
    SELECT       OFFC.PROV_ID
    ,       MIN (CASE WHEN OFFC.WK_DAY ='MONDAY'    THEN OFFC.OFFC_OPENG_TIME END)     AS mon_opn
    ,       MIN (CASE WHEN OFFC.WK_DAY ='MONDAY'    THEN OFFC.OFFC_CLSNG_TIME END)     AS mon_cls
    ,       MIN (CASE WHEN OFFC.WK_DAY ='TUESDAY'   THEN OFFC.OFFC_OPENG_TIME END)     AS tue_opn
    ,       MIN (CASE WHEN OFFC.WK_DAY ='TUESDAY'   THEN OFFC.OFFC_CLSNG_TIME END)     AS tue_cls
    FROM        GGDD.PROV_OFFC_HR OFFC
    WHERE       OFFC.PROV_ID     = '0000600'
    GROUP BY  offc.prov_id
    ;This assumes there is (at most) only one row in the table for each distinct prov_id and weekday. If not, what do you want to do? Post a little sample data (CREATE TABLE and INSERT statements) and the results you want from that data.
    The staement above works in Oracle 8.1 and up, but there's a better way (SELECT ... PIVOT) available in Oracle 11. What version are you using? (It's always a good idea to include this when you post a question.)
    Edited by: Frank Kulash on Jan 6, 2011 8:22 PM

  • Query cost and CASE statement

    Hi, I'm working on a performance issue for a customer.
    I'm tuning some suspect SQL that uses complex DECODE statements to perform IF/THEN/ELSE logic.
    I've taken a statement and rewritten it using CASE however what I've noticed is the cost of the query execution plan has increased dramatically as a result. N.B. I haven't changed the WHERE clause of the query as yet, just replaced one DECODE with the equivalent CASE.
    The db version is 9.2.0.4. Does anyone know of issues with the performance of CASE as opposed to DECODE. I'm wondering should I leave the DECODEs as is even though they're way too complicated.
    Tks,
    Paul.

    Here's an example of a DECODE:
    nvl(count(distinct decode
    (decode(sign(ords.dwh_created_date_id-:v_start_cycle_id),1,1,0,1,-1,0) *
    decode(sign(:v_end_cycle_id-ords.dwh_created_date_id),1,1,0,1,-1,0),1,ords.dwh_order_id,NULL)),0) calc1
    The equivalent CASE I've coded is:
    NVL(COUNT(DISTINCT(CASE WHEN (ords.dwh_created_date_id BETWEEN :v_start_cycle_id AND :v_end_cycle_id)
    THEN
    ords.dwh_order_id
    ELSE
    NULL
    END)),0) calc1
    I've been doing further testing with an amended WHERE clause and did run both CASE and DECODE versions. The performance difference between the two was negligible. So it seems (as I'd hoped) that the amendment of the execution path doesn't appear to be affected by CASE even though Oracle reports the query cost of it is higher.
    It is slightly confusing though. Is the query cost in this case a red herring ?

  • Case statement problems in oracle forms 6i

    Hello,
    Any one can help me that how to use case statment in Oracle forms 6i.
    i have read one thread and there was no proper solution so could any one please let me know to use case statement.
    Please also let me know which category i should search for FORMS 6i.
    when i'm using below code with cursor then i'm getting error 103
    database:=11g
    application := forms 6i
    operating system:= win Xp
    code is given below :-
    cursor c1 is
    select nc.nomenclature_id,
    nvl(nc.category_value, 0) master,
    nvl(nc2.category_value, 0) case,
    nvl(nc3.category_value, 0) bundle,
    case
    when nvl(nc.category_value, 0) > 0 and
    nvl(nc2.category_value, 0) > 0 and
    nvl(nc3.category_value, 0) > 0 then
    'A' --All packouts Master, Case, Bundle
    when nvl(nc.category_value, 0) > 0 and
    nvl(nc2.category_value, 0) > 0 and
    nvl(nc3.category_value, 0) = 0 then
    'B' --Both Master and Case
    when nvl(nc2.category_value, 0) = 0 and
    nvl(nc3.category_value, 0) = 0 then
    'C' --Master Case Only
    else
    'N'
    end code
    from nomn_category nc, --master case
    (select nc2.nomenclature_id,
    nc2.category_value
    from nomn_category nc2
    where nc2.category_id = '230732') nc2,
    (select nc3.nomenclature_id,
    nc3.category_value
    from nomn_category nc3
    where nc3.category_id = '236566') nc3
    Edited by: Rahul on Feb 3, 2012 7:18 PM
    Edited by: Rahul on Feb 3, 2012 7:20 PM

    hello Andreas,
    It is ok but i dont have to use view there.
    i need to use without view, because this code has to be use in FORMS6i.
    But Forms6i doesn't support to case function. i'm newbie in Forms.
    If you can convert to below bold one portion(case) into decode then please help me or
    if you have any idea about Forms6i then please send me any link where is given explanation about excel report that how to make excel report through Forms6i step by step and that excel report should be generate on any dynamic path which is given by user:-
    cursor c1 is
    select nc.nomenclature_id,
    nvl(nc.category_value, 0) master,
    nvl(nc2.category_value, 0) case,
    nvl(nc3.category_value, 0) bundle,
    case
    when nvl(nc.category_value, 0) > 0 and
    nvl(nc2.category_value, 0) > 0 and
    nvl(nc3.category_value, 0) > 0 then
    *'A'*
    when nvl(nc.category_value, 0) > 0 and
    nvl(nc2.category_value, 0) > 0 and
    nvl(nc3.category_value, 0) = 0 then
    *'B' --Both Master and Case*
    when nvl(nc2.category_value, 0) = 0 and
    nvl(nc3.category_value, 0) = 0 then
    *'C'*
    else
    *'N'*
    end "code"
    from nomn_category nc,
    (select nc2.nomenclature_id,
    nc2.category_value
    from nomn_category nc2
    where nc2.category_id = '230732') nc2,
    (select nc3.nomenclature_id,
    nc3.category_value
    from nomn_category nc3
    where nc3.category_id = '236566') nc3
    thanks

  • Help needed in SQL performance - Using CASE in SQL statement versus 2 query

    Hi,
    I have a requirement to find count from a bunch of tables.
    The SQL I have gives the count of all members.
    I have created 2 queries to find count of active and inactive members.
    The key difference is only the active dates.
    Each query takes 20 seconds to execute.
    I modified the SQL to use CASE statement in the SELECT.
    So after the data is fetched the CASE statement will evaluate the active date and gives 2 counts (active and inactive)
    Is it advisable to use this approach. Will CASE improve SQL performance ? I have to justify this.
    Please let me know your thoughts.
    Thanks,
    J

    Hi,
    If it can be done in single SQL do it in single SQL.
    You said:
    Will CASE improve SQL performance There can be both cases to prove if the performance is better or worse.
    In your case you should tell us how it is.
    Regards,
    Bhushan

  • Case statement in a multiple query

    Hi everyone,
    This is my first time to use case statement in a multiple query. I have tried to implement it but i got no luck.. Please see below
    set define off
    SELECT g.GROUP_NAME as Market
    ,t.NAME as "Template Name"
    ,t.TEMPLATE_ID as "Template ID"
    ,(SELECT created
    FROM material
    where template_id = t.template_id) as "Date Created"
    *,(SELECT DESTINATION_FOLDER_ID,*
    CASE DESTINATION_FOLDER_ID
    WHEN NULL THEN 'Upload'
    ELSE 'HQ'
    END
    from log_material_copy
    where destination_material_id in (select material_id
    from material
    where template_id = t.template_id ))as "Origin"
    ,(select material_id
    from log_material_copy
    where destination_material_id in (select material_id
    from material
    where template_id = t.template_id)) as "HQ/Upload ID"
    ,(SELECT COUNT (mse.ID)
    FROM MATERIAL_SEND_EVENT mse, material m, creative c
    WHERE mse.MATERIAL_ID = m.MATERIAL_ID
    AND mse.MATERIAL_TYPE_ID = m.MATERIAL_TYPE_ID
    AND m.ASSET_ID = c.id
    AND c.TEMPLATE_ID = t.TEMPLATE_ID) as Sent
    ,(SELECT COUNT (de.ID)
    FROM download_event de, material m, creative c
    WHERE de.MATERIAL_ID = m.MATERIAL_ID
    AND de.MATERIAL_TYPE_ID = m.MATERIAL_TYPE_ID
    AND m.ASSET_ID = c.id
    AND c.TEMPLATE_ID = t.TEMPLATE_ID) as Download
    ,(SELECT 'https://main.test.com/bm/servlet/' || 'UArchiveServlet?action=materialInfo&materialId=' || DESTINATION_MATERIAL_ID || '&materialFolderId=' || DESTINATION_FOLDER_ID
    from log_material_copy
    where destination_material_id in (select material_id
    from material
    where template_id = t.template_id)) as "URL to template on MPC layer"
    --, t.AVAILABLE_FOR_TRANSFER as "Available for transfer"
    FROM template t, layout l, groups g
    WHERE t.LAYOUT_ID = l.LAYOUT_ID
    AND l.ORGANIZATION_ID = g.IP_GROUPID
    AND g.IP_GROUPID in ( 1089, 903, 323, 30, 96, 80, 544, 1169, 584, 785, 827, 31, 10, 503, 1025 )
    ORDER BY g.GROUP_NAME ASC;
    The one in bold is my case statement.. Please let me know what is wrong with this.
    Regards,
    Jas

    I think you're getting the idea, but:
    You're still selecting 2 columns in the (scalar) subquery. Did you read the link I posted for you?
    "a) scalar subqueries - *a single row, single column query that you use in place of a "column"*, it looks like a column or function."
    You must move that query outside, join to template.
    Something like:
    NOT TESTED FOR OBVIOUS REASONS SO YOU'LL PROBABLY NEED TO TWEAK IT A BIT
    select g.group_name as market,
           t.name as "Template Name",
           t.template_id as "Template ID",
           m.created  as "Date Created",
           lmc.destination_folder_id,
           case lmc.destination_folder_id
             when null then 'Upload'
             else 'HQ'
           end as "Origin"
           (select material_id
              from log_material_copy
             where destination_material_id in
                   (select material_id
                      from material
                     where template_id = t.template_id)) as "HQ/Upload ID"
           (select count(mse.id)
              from material_send_event mse, material m, creative c
             where mse.material_id = m.material_id
               and mse.material_type_id = m.material_type_id
               and m.asset_id = c.id
               and c.template_id = t.template_id) as sent
           (select count(de.id)
              from download_event de, material m, creative c
             where de.material_id = m.material_id
               and de.material_type_id = m.material_type_id
               and m.asset_id = c.id
               and c.template_id = t.template_id) as download
           (select 'https://main.test.com/bm/servlet/' ||
                   'UArchiveServlet?action=materialInfo&materialId=' ||
                   destination_material_id || '&materialFolderId=' ||
                   destination_folder_id
              from log_material_copy
             where destination_material_id in
                   (select material_id
                      from material
                     where template_id = t.template_id)) as "URL to template on MPC layer"
    --, t.AVAILABLE_FOR_TRANSFER as "Available for transfer"
      from template t
      ,    layout l
      ,    groups group by
      ,    MATERIAL M
      ,    LOG_MATERIAL_COPY LMC
    where t.layout_id = l.layout_id
       and l.organization_id = g.ip_groupid
       and M.TEMPLATE_ID = t.template_id
       and LMC.destination_material_id in ( select material_id
                                            from   material
                                            where  template_id = t.template_id
       and g.ip_groupid in (1089,
                            903,
                            323,
                            30,
                            96,
                            80,
                            544,
                            1169,
                            584,
                            785,
                            827,
                            31,
                            10,
                            503,
                            1025)
    order by g.group_name asc;

  • Query Tuning - using CASE statement in the WHERE clause

    Hi All,
    My query has been modified to use a CASE statement in the WHERE clause to consider data from certain columns based on a parameter value. This modified query is doing a full table scan and running endlessly. Please suggest what may be done to improve its performance:
    Query:
    SELECT LAST_DAY(TRUNC(TO_TIMESTAMP(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))) AS summary_date,
    os.acctnum,
    os.avieworigin_refid,
    COUNT(1) cnt_articleview,
    SUM(NVL(autocompletedterm,0)) cnt_autocompletedterm
    FROM TABLE1 os
    WHERE os.acctnum IS NOT NULL
    AND os.avieworigin_refid IS NOT NULL
    AND os.requestdatetime IS NOT NULL
    AND UPPER(os.success_ind) = 'S'
    AND CASE WHEN
    Param_ValueToCheck  = 'FULL' AND get_date_timestamp(os.requestdatetime)  BETWEEN
    TO_DATE('01-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND
    TO_DATE('31-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
    THEN 1
    WHEN
    Param_ValueToCheck  = 'INCR' AND os.entry_createddate  BETWEEN
    TO_DATE('01-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND
    TO_DATE('31-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
    THEN 1
    END = 1
    AND CASE WHEN
    Param_ValueToCheck  = 'FULL' AND os.entry_CreatedDate BETWEEN
    TO_DATE('01-APR-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND
    TO_DATE('07-JUN-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
    THEN 1
    WHEN
    Param_ValueToCheck  = 'INCR' THEN 1
    END = 1
    GROUP BY LAST_DAY(TRUNC(TO_TIMESTAMP(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))), os.acctnum,os.avieworigin_refid;Table Description:
    (Number of rows : approx > 600,000,000)
    Name                           Null     Type      
    ARTICLEID                      NOT NULL NUMBER(20)
    USERKEY                                 NUMBER(10)
    AVIEWORIGIN_REFID                       VARCHAR2(10)
    SUCCESS_IND                             VARCHAR2(2)
    ENTRY_CREATEDDATE                       DATE      
    CREATED_BY                              VARCHAR2(10)
    FILENUMBER                              NUMBER(10)
    LINENUMBER                              NUMBER(10)
    ACCTNUM                                 VARCHAR2(10)
    AUTOCOMPLETEDTERM                       NUMBER(2) 
    REQUESTDATETIME                         VARCHAR2(19)Explain Plan
    SQL> select * from table(dbms_xplan.display);
    PLAN_TABLE_OUTPUT
    Plan hash value: 2224314832
    | Id  | Operation            | Name              | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
    |   0 | SELECT STATEMENT     |                   |   590 | 33040 |  2501K  (1)| 08:20:15 |       |       |
    |   1 |  HASH GROUP BY       |                   |   590 | 33040 |  2501K  (1)| 08:20:15 |       |       |
    |   2 |   PARTITION RANGE ALL|                   |   590 | 33040 |  2501K  (1)| 08:20:15 |     1 |1048575|
    |*  3 |    TABLE ACCESS FULL | TABLE1 |   590 | 33040 |  2501K  (1)| 08:20:15 |     1 |1048575|
    PLAN_TABLE_OUTPUT
    Predicate Information (identified by operation id):
       3 - filter(UPPER("OS"."SUCCESS_IND")='S' AND CASE  WHEN ('FULL'='FULL' AND
                  "OS"."ENTRY_CREATEDDATE">=TO_DATE(' 2011-04-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
                  "OS"."ENTRY_CREATEDDATE"<=TO_DATE(' 2011-06-07 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) THEN 1 WHEN
                  'FULL'='INCR' THEN 1 END =1 AND "OS"."REQUESTDATETIME" IS NOT NULL AND CASE  WHEN ('FULL'='FULL'
                  AND "ODS"."GET_DATE_TIMESTAMP"("REQUESTDATETIME")>=TO_DATE(' 2011-05-01 00:00:00', 'syyyy-mm-dd
                  hh24:mi:ss') AND "ODS"."GET_DATE_TIMESTAMP"("REQUESTDATETIME")<=TO_DATE(' 2011-05-31 00:00:00',
                  'syyyy-mm-dd hh24:mi:ss')) THEN 1 WHEN ('FULL'='INCR' AND "OS"."ENTRY_CREATEDDATE">=TO_DATE('
                  2011-05-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "OS"."ENTRY_CREATEDDATE"<=TO_DATE('
    PLAN_TABLE_OUTPUT
                  2011-05-31 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) THEN 1 END =1 AND "OS"."ACCTNUM" IS NOT NULL AND
                  "OS"."AVIEWORIGIN_REFID" IS NOT NULL)Edited by: Chaitanya on Jun 9, 2011 2:44 AM
    Edited by: Chaitanya on Jun 9, 2011 2:47 AM

    Hi Dom,
    Modified Query:
    SELECT LAST_DAY(TRUNC(TO_TIMESTAMP(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))) AS summary_date,
    os.acctnum,
    os.avieworigin_refid,
    COUNT(1) cnt_articleview,
    SUM(NVL(autocompletedterm,0)) cnt_autocompletedterm
    FROM TABLE1 os
    WHERE os.acctnum IS NOT NULL
    AND os.avieworigin_refid IS NOT NULL
    AND os.requestdatetime IS NOT NULL
    AND UPPER(os.success_ind) = 'S'
    AND (('FULL'  = 'FULL'
    AND  (get_date_timestamp(os.requestdatetime)  BETWEEN TO_DATE('01-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
                   AND TO_DATE('31-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
    AND   os.entry_CreatedDate BETWEEN TO_DATE('01-APR-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
                   AND TO_DATE('07-JUN-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
    OR ('FULL'  = 'INCR'
    AND os.entry_createddate  BETWEEN TO_DATE('01-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
                   AND TO_DATE('31-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') ))
    GROUP BY LAST_DAY(TRUNC(TO_TIMESTAMP(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))), os.acctnum,os.avieworigin_refid;Execute Plan:
    PLAN_TABLE_OUTPUT
    Plan hash value: 3615447714
    | Id  | Operation                 | Name              | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
    |   0 | SELECT STATEMENT          |                   | 25125 |  1374K|       |   407K  (1)| 01:21:36 |       |       |
    |   1 |  HASH GROUP BY            |                   | 25125 |  1374K|  3768K|   407K  (1)| 01:21:36 |       |       |
    |   2 |   PARTITION RANGE ITERATOR|                   | 25125 |  1374K|       |   407K  (1)| 01:21:32 |    29 |    31 |
    |*  3 |    TABLE ACCESS FULL      | TABLE1 | 25125 |  1374K|       |   407K  (1)| 01:21:32 |    29 |    31 |
    PLAN_TABLE_OUTPUT
    Predicate Information (identified by operation id):
       3 - filter("OS"."ENTRY_CREATEDDATE">=TO_DATE(' 2011-04-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
                  UPPER("OS"."SUCCESS_IND")='S' AND "OS"."REQUESTDATETIME" IS NOT NULL AND
                  "ODS"."GET_DATE_TIMESTAMP"("REQUESTDATETIME")>=TO_DATE(' 2011-05-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
                  "ODS"."GET_DATE_TIMESTAMP"("REQUESTDATETIME")<=TO_DATE(' 2011-05-31 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
                  "OS"."ACCTNUM" IS NOT NULL AND "OS"."AVIEWORIGIN_REFID" IS NOT NULL AND "OS"."ENTRY_CREATEDDATE"<=TO_DATE('
                  2011-06-07 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))Edited by: Chaitanya on Jun 9, 2011 4:51 AM

Maybe you are looking for