How to optimize this sql by writing MINUS function.

Hi all,
how to optimize the sql by writing MINUS function.
these are my tables
1. CREATE TABLE POSTPAID
RECORD VARCHAR2(2000 BYTE),
FLAG NUMBER
Record format:
Mobile no in 1:10 of that length
2. CREATE TABLE SUBSCRIBER
PHONE_NO VARCHAR2(10 BYTE)
My requirement is following sql need write using ‘minus’ as this one is very slow
select record record from POSTPAID where substr(record,9,10) NOT in (select PHONE_NO from SUBSCRIBER)
Thanks

Why are you very particular about using "MINUS". You can optimize the sql by using "NOT EXISTS" instead of "NOT IN" as below:
SELECT RECORD FROM POSTPAID A WHERE NOT EXISTS (SELECT 1 FROM SUBSCRIBER B WHERE SUBSTR(A.RECORD,9,10) = B.PHONE_NO)

Similar Messages

  • How to optimize this SQL. Help needed.

    Hi All,
    Can you please help with this SQL:
    SELECT /*+ INDEX(zl1 zipcode_lat1) */
    zl2.zipcode as zipcode,l.location_id as location_id,
    sqrt(POWER((69.1 * ((zl2.latitude*57.295779513082320876798154814105) - (zl1.latitude*57.295779513082320876798154814105))),2) + POWER((69.1 * ((zl2.longitude*57.295779513082320876798154814105) - (zl1.longitude*57.295779513082320876798154814105)) * cos((zl1.latitude*57.295779513082320876798154814105)/57.3)),2)) as distance
    FROM location_atao l, zipcode_atao zl1, client c, zipcode_atao zl2
    WHERE zl1.zipcode = l.zipcode
    AND l.client_id = c.client_id
    AND c.client_id = 306363
    And l.appType = 'HOURLY'
    and c.milessearchzipcode >= sqrt(POWER((69.1 * ((zl2.latitude*57.295779513082320876798154814105) - (zl1.latitude*57.295779513082320876798154814105))),2) + POWER((69.1 * ((zl2.longitude*57.295779513082320876798154814105) - (zl1.longitude*57.295779513082320876798154814105)) * cos((zl1.latitude*57.295779513082320876798154814105)/57.3)),2))
    I tried to optimize it by adding country column in zipcode_atao table. So that we can limit the search in zipcode_atao table based on country.
    Any other suggestions.
    Thanks

    Welcome to the forum.
    Please follow the instructions given in this thread:
    How to post a SQL statement tuning request
    HOW TO: Post a SQL statement tuning request - template posting
    and add the nessecary details we need to your thread.
    Depending on your database version (the result of: select * from v$version; ):
    Have you tried running the query without the index-hint?
    Are your table (and index) statatistics up-to-date?

  • How to optimize this SQL?

    Hi All!
    For example I have to records from a table:
    Value1 Value2 Day_ID
    000001 000002 20031211
    000001 000002 20031219
    You can see, that value 1 and 2 are the same in both records. Only Day_IDs are different. So I need to find a record with max(Day_ID). This is my SQL:
    select *
    from MyTable
    where day_id = (select max(day_id) from MyTable)
    Is there any way to get the same result without sub select?
    Any help will be appreciate.
    With best regards,
    Andrej Litowka.

    ORA-00937: not a single-group group functionThen you must have a non-aggregated column in your SELECT clause that is not in your GROUP BY clause.
    Let's be careful out there!
    APC

  • I don't know how I can optimize this SQL

    Dear ALL:
    I don't know how I can optimize this SQL.
    Is it possible to make a better SQL or PL/SQL?
    Please let me know your good thought.
    Thank you.
    Sincerely,
    ===========================================================
    (SELECT     A, B, C, SUM(D) as D, AVG(E) as E
    FROM      T1, T2
    WHERE     T1.timestamp BETWEEN TO_DATE('00:00:00','HH24:MI:SS')
    AND TO_DATE('01:00:00','HH24:MI:SS')
    GROUP BY A, B, C
    UNION ALL
    (SELECT     A, B, C, SUM(D) as D, AVG(E) as E
    FROM      T1, T2
    WHERE     T1.timestamp BETWEEN TO_DATE('01:00:01','HH24:MI:SS')
    AND TO_DATE('02:00:00','HH24:MI:SS')
    GROUP BY A, B, C
    UNION ALL
    (SELECT     A, B, C, SUM(D) as D, AVG(E) as E
    FROM      T1, T2
    WHERE     T1.timestamp BETWEEN TO_DATE('02:00:01','HH24:MI:SS')
    AND TO_DATE('03:00:00','HH24:MI:SS')
    GROUP BY A, B, C
    UNION ALL
    (SELECT     A, B, C, SUM(D) as D, AVG(E) as E
    FROM      T1, T2
    WHERE     T1.timestamp BETWEEN TO_DATE('03:00:01','HH24:MI:SS')
    AND TO_DATE('04:00:00','HH24:MI:SS')
    GROUP BY A, B, C
    ORDER BY A ASC, B ASC, C ASC
    ===========================================================

    Dear Warren:
    Actually, for this query, it takes a few second to complete the query.
    But, I have to create several time period and I have to optimize the SQL.
    Time period is 1 hour, 30 min, 15 min, 5 min.
    That is,
    ===========================================================
    WHERE T1.timstamp BETWEEN TO_DATE('00:00:00','HH24:MI:SS')
    AND TO_DATE('01:00:00','HH24:MI:SS')
    UNION ALL
    WHERE T1.timestamp BETWEEN TO_DATE('23:00:01','HH24:MI:SS')
    AND TO_DATE('24:00:00','HH24:MI:SS')
    ===========================================================
    WHERE T1.timstamp BETWEEN TO_DATE('00:00:00','HH24:MI:SS')
    AND TO_DATE('00:30:00','HH24:MI:SS')
    UNION ALL
    WHERE T1.timestamp BETWEEN TO_DATE('23:30:01','HH24:MI:SS')
    AND TO_DATE('24:00:00','HH24:MI:SS')
    ===========================================================
    WHERE T1.timstamp BETWEEN TO_DATE('00:00:00','HH24:MI:SS')
    AND TO_DATE('00:15:00','HH24:MI:SS')
    UNION ALL
    WHERE T1.timestamp BETWEEN TO_DATE('23:45:01','HH24:MI:SS')
    AND TO_DATE('24:00:00','HH24:MI:SS')
    ===========================================================
    WHERE T1.timstamp BETWEEN TO_DATE('00:00:00','HH24:MI:SS')
    AND TO_DATE('00:05:00','HH24:MI:SS')
    UNION ALL
    WHERE T1.timestamp BETWEEN TO_DATE('23:55:01','HH24:MI:SS')
    AND TO_DATE('24:00:00','HH24:MI:SS')
    ===========================================================
    Do you know how this SQL is optimized?
    Thank you,

  • How can i optimize this SQL

    Is there anyway i could optimize the below mentioned SQL. Since our test DB is down now, i'll be posting the EXPLAIN PLAN later.
    Is there anything i could do syntactically to optimize this sql?
    SELECT SUBSTR(STK_INF.TASK_GENRTN_REF_NBR,1,12) AS PICK_WAVE_NBR,
                     ( CASE WHEN ( SUM(STK_INF.QTY_ALLOC) > 0 ) THEN
            ROUND ( (SUM(CASE WHEN (STK_INF.NEXT_TASK_ID = 0 AND STK_INF.ALLOC_INVN_DTL_ID = 0) THEN
            STK_INF.QTY_ALLOC ELSE 0 END ) / (SUM(STK_INF.QTY_ALLOC))),2 ) * 100
            ELSE 0 END ) AS PICK_PER,
         ( CASE WHEN ( SUM(STK_INF.QTY_ALLOC) > 0 ) THEN
           ROUND( (SUM(CASE WHEN (STK_INF.NEXT_TASK_ID = 0 AND STK_INF.ALLOC_INVN_DTL_ID = 0) THEN
           STK_INF.QTY_PULLD ELSE 0 END ) / (SUM(STK_INF.QTY_ALLOC))),2 ) * 100
           ELSE 0 END ) AS TILT_PERCENT
         FROM STK_INF, TRK_DTL
         WHERE STK_INF.TASK_GENRTN_REF_CODE = '44' AND STK_INF.CARTON_NBR IS NOT NULL
          AND ((STK_INF.NEXT_TASK_ID = 0 AND STK_INF.STAT_CODE <= 90) OR (STK_INF.NEXT_TASK_ID > 0 AND STK_INF.STAT_CODE < 99))
          AND PULL_LOCN_ID = TRK_DTL.LOCN_ID(+) AND (TRK_DTL.AREA <>'C' OR TRK_DTL.AREA IS NULL)
         GROUP BY SUBSTR(STK_INF.TASK_GENRTN_REF_NBR,1,12)

    This is the EXPLAIN PLAIN i got after i issued EXECUTE DBMS_STATS.GATHER_TABLE_STATS ('schema_name','table_name'); for both the tables involved.
    The number of row returned is still 222 rows. But in the EXPLAIN PLAN it is shown as 3060 !!
    SQL> select * from table(dbms_xplan.display);
    PLAN_TABLE_OUTPUT
    Plan hash value: 3267659036
    | Id  | Operation               | Name     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT        |          |  3060 |   194K|       | 16527  (10)| 00:03:19 |
    |   1 |  HASH GROUP BY          |          |  3060 |   194K|       | 16527  (10)| 00:03:19 |
    |*  2 |   FILTER                |          |       |       |       |            |          |
    |*  3 |    HASH JOIN RIGHT OUTER|          |   177K|    11M|  7344K| 16397  (10)| 00:03:17 |
    |   4 |     TABLE ACCESS FULL   | TRK_DTL |   313K|  3669K|       |  2378   (6)| 00:00:29 |
    |*  5 |     TABLE ACCESS FULL   | STK_INF |   177K|  9205K|       | 13030  (11)| 00:02:37 |
    PLAN_TABLE_OUTPUT
    Predicate Information (identified by operation id):
       2 - filter("TRK_DTL"."AREA"<>'C' OR "TRK_DTL"."AREA" IS NULL)
       3 - access("PULL_LOCN_ID"="TRK_DTL"."LOCN_ID"(+))
       5 - filter("STK_INF"."CARTON_NBR" IS NOT NULL AND
                  "STK_INF"."TASK_GENRTN_REF_CODE"='44' AND ("STK_INF"."NEXT_TASK_ID"=0 AND
                  "STK_INF"."STAT_CODE"<=90 OR "STK_INF"."NEXT_TASK_ID">0 AND
                  "STK_INF"."STAT_CODE"<99))
    22 rows selected.You mentioned about creating indexes in STK_INF table. STK_INF.NEXT_TASK_ID has 186385 distinct values out of a total 782087. Does NEXT_TASK_ID make a good candidate for a B-Tree index
    STK_INF.STAT_CODE has only four distinct values, would this make a good candidate for a Bitmap index?

  • How to execute this SQL Query in ABAP Program.

    Hi,
    I have a string which is the SQL Query.
    How to execute this sql Query (SQL_STR) in ABAP Program.
    Code:-
    DATA: SQL_STR type string.
    SQL_STR = 'select * from spfli.'.
    Thanks in Advance,
    Vinay

    Hi Vinay
    Here is a sample to dynamically generate a subroutine-pool having your SQL and calling it.
    REPORT dynamic_sql_example .
    DATA: BEGIN OF gt_itab OCCURS 1 ,
    line(80) TYPE c ,
    END OF gt_itab .
    DATA gt_restab TYPE .... .
    DATA gv_name(30) TYPE c .
    DATA gv_err(120) TYPE c .
    START-OF-SELECTION .
    gt_itab-line = 'REPORT generated_sql .' .
    APPEND gt_itab .
    gt_itab-line = 'FORM exec_sql CHANGING et_table . ' .
    APPEND gt_itab .
    gt_itab-line = SQL_STR .
    APPEND gt_itab .
    gt_itab-line = 'ENDFORM.' .
    APPEND gt_itab .
    GENERATE SUBROUTINE POOL gt_itab NAME gv_name MESSAGE gv_err .
    PERFORM exec_sql IN PROGRAM (gv_name) CHANGING gt_restab
    IF FOUND .
    WRITE:/ gv_err .
    LOOP AT gt_result .
    WRITE:/ .... .
    ENDLOOP .
    *--Serdar

  • How to optimize this select statement  its a simple select....

    how to optimize this select statement  as the records in earlier table is abt i million
    and this simplet select statement is not executing and taking lot of time
      SELECT  guid  
                    stcts      
      INTO table gt_corcts
      FROM   corcts
      FOR all entries in gt_mege
      WHERE  /sapsll/corcts~stcts = gt_mege-ctsex
      and /sapsll/corcts~guid_pobj = gt_Sagmeld-guid_pobj.
    regards
    Arora

    Hi Arora,
    Using Package size is very simple and you can avoid the time out and as well as the problem because of memory.  Some time if you have too many records in the internal table, then you will get a short dump called TSV_TNEW_PAGE_ALLOC_FAILED.
    Below is the sample code.
    DATA p_size = 50000
    SELECT field1 field2 field3
       INTO TABLE itab1 PACKAGE SIZE p_size
       FROM dtab
       WHERE <condition>
    Other logic or process on the internal table itab1
    FREE itab1.
    ENDSELECT.
    Here the only problem is you have to put the ENDSELECT.
    How it works
    In the first select it will select 50000 records ( or the p_size you gave).  That will be in the internal table itab1.
    In the second select it will clear the 50000 records already there and append next 50000 records from the database table.
    So care should be taken to do all the logic or process with in select and endselect.
    Some ABAP standards may not allow you to use select-endselect.  But this is the best way to handle huge data without short dumps and memory related problems. 
    I am using this approach.  My data is much more huge than yours.  At an average of atleast 5 millions records per select.
    Good luck and hope this help you.
    Regards,
    Kasthuri Rangan Srinivasan

  • What is the best way to Optimize a SQL query : call a function or do a join?

    Hi, I want to know what is the best way to optimize a SQL query, call a function inside the SELECT statement or do a simple join?

    Hi,
    If you're even considering a join, then it will probably be faster.  As Justin said, it depends on lots of factors.
    A user-defined function is only necessary when you can't figure out how to do something in pure SQL, using joins and built-in functions.
    You might choose to have a user-defined function even though you could get the same result with a join.  That is, you realize that the function is slow, but you believe that the convenience of using a function is more important than better performance in that particular case.

  • How I can optimize this SQL query

    I require your help, I want to know how I can optimize this query
    SELECT
                    "F42119". "SDLITM" as "Code1"
                    "F42119". "SDAITM" as "Code2"
                    "F42119". "SDDSC1" as "Product"
                    "F42119". "SDMCU" as "Bodega"
                    Sum ("F42119". "SDSOQS" / 10000) as "Number",
                    Sum ("F42119". "SDUPRC" / 10000) as "preciou"
                    Sum ("F42119". "SDAEXP" / 100) as "Value",
                    Sum ("F42119". "SDUNCS" / 10000) as "CostoU"
                    Sum ("F42119". "SDECST" / 100) as "Cost"
                    "F4101". "IMSRP1" as "Division"
                    "F4101". "IMSRP2" as "classification",
                    "F4101". "IMSRP8" as "Brand"
                    "F4101". "IMSRP9" as "Aroma"
                    "F4101". "IMSRP0" as "Presentation"
                    "F42119". "SDDOC" as "Type",
                    "F42119". "SDDCT" as "Document",
                    "F42119". "SDUOM" as "Unit"
                    "F42119". "SDCRCD" as "currency"
                    "F0101". "ABAN8" as "ABAN8"
                    "F0101". "ABALPH" as "Customer"
                    "F0006". "MCRP22" as "Establishment"
    from          "PRODDTA". "F0101" "F0101"
                    "PRODDTA". "F42119" "F42119"
                    "PRODDTA". "F4101" "F4101"
                    "PRODDTA". "F0006" "F0006"
    where       "F42119". "SDAN8" = "F0101". "ABAN8"
      and         "F0006". "MCMCU" = "F42119". "SDMCU"
      and         "F4101". "IMITM" = "F42119". "SDITM"
      and         "F42119". "SDDCT" in ('RI', 'RM', 'RN')
      and         CAST (EXTRACT (MONTH FROM TO_DATE (substr ((to_date ('01-01-'| | to_char (round (1900 + (CAST ("F42119". "SDDGL" as int) / 1000))),' DD- MM-                YYYY ') + substr (to_char (CAST ("F42119". "SDDGL" as int)), 4,3) -1), 1,10))) AS INT) in : Month
    and          CAST (EXTRACT (YEAR FROM TO_DATE (substr ((to_date ('01-01-'| | to_char (round (1900 + (CAST ("F42119". "SDDGL" as int) / 1000))),' DD- MM-                YYYY ')+ Substr (to_char (CAST ("F42119". "SDDGL" as int)), 4,3) -1), 1,10))) AS INT) in: Year
    and          trim ("F0006". "MCRP22") =: Establishment
    and          trim ("F4101". "IMSRP1") =: Division
    Group By    "F42119". "SDLITM"
                    "F42119". "SDAITM"
                    "F42119". "SDDSC1"
                    "F4101". "IMSRP1"
                    "F42119". "SDDOC"
                    "F42119". "SDDCT"
                    "F42119". "SDUOM"
                    "F42119". "SDCRCD"
                    "F0101". "ABAN8"
                    "F0101". "ABALPH"
                    "F4101". "IMSRP2"
                    "F4101". "IMSRP8"
                    "F4101". "IMSRP9"
                    "F4101". "IMSRP0"
                    "F42119". "SDMCU"
                    "F0006". "MCRP22"
    I appreciate the help you can give me

    It seems to me that part of fixing it could be how you join the tables.
    Instead of the humongous where clause, put the applicable conditions on the join.
    You have
    from "PRODDTA". "F0101" "F0101"
    "PRODDTA". "F42119" "F42119"
    "PRODDTA". "F4101" "F4101"
    "PRODDTA". "F0006" "F0006"
    where "F42119". "SDAN8" = "F0101". "ABAN8"
    and "F0006". "MCMCU" = "F42119". "SDMCU"
    and "F4101". "IMITM" = "F42119". "SDITM"
    and "F42119". "SDDCT" in ('RI', 'RM', 'RN')
    and CAST (EXTRACT (MONTH FROM TO_DATE (substr ((to_date ('01-01-'| | to_char (round (1900 + (CAST ("F42119". "SDDGL" as int) / 1000))),' DD- MM- YYYY ') + substr (to_char (CAST ("F42119". "SDDGL" as int)), 4,3) -1), 1,10))) AS INT) in : Month
    and CAST (EXTRACT (YEAR FROM TO_DATE (substr ((to_date ('01-01-'| | to_char (round (1900 + (CAST ("F42119". "SDDGL" as int) / 1000))),' DD- MM- YYYY ')+ Substr (to_char (CAST ("F42119". "SDDGL" as int)), 4,3) -1), 1,10))) AS INT) in: Year
    and trim ("F0006". "MCRP22") =: Establishment
    and trim ("F4101". "IMSRP1") =: Division
    INSTEAD try something like
    from JOIN "PRODDTA". "F0101" "F0101" ON "F42119". "SDAN8" = "F0101". "ABAN8"
    JOIN "PRODDTA". "F42119" "F42119" ON "F0006". "MCMCU" = "F42119". "SDMCU"
    JOIN "PRODDTA". "F4101" "F4101" ON join condition
    JOIN "PRODDTA". "F0006" "F0006" ON join condition.
    Not sure exactly how you need things joined, but above is the basic idea. Remove criteria for joining the tables from the WHERE clause and put them
    in the join statements. That might clean things up and make it more efficient.

  • Need help on how to code this SQL statement! (one key has leading zeros)

    Good day, everyone!
    First of all, I apologize if this isn't the best forum.  I thought of putting it in the SAP Oracle database forum, but the messages there seemed to be geared outside of ABAP SELECTs and programming.  Here's my question:
    I would like to join the tables FMIFIIT and AUFK.  The INNER JOIN will be done between FMIFIIT's MEASURE (Funded Program) field, which is char(24), and AUFK's AUFNR (Order Number) field, which is char(12).
    The problem I'm having is this:  All of the values in AUFNR are preceeded by two zeros.  For example, if I have a MEASURE value of '5200000017', the corresponding value in AUFNR is '005200000017'.  Because I have my SQL statement coded to just match the two fields, I obviously get no records returned because, I assume, of those leading zeros.
    Unfortunately, I don't have a lot of experience coding SQL, so I'm not sure how to resolve this.
    Please help!  As always, I will award points to ALL helpful responses!
    Thanks!!
    Dave

    >
    Dave Packard wrote:
    > Good day, everyone!
    > I would like to join the tables FMIFIIT and AUFK.  The INNER JOIN will be done between FMIFIIT's MEASURE (Funded Program) field, which is char(24), and AUFK's AUFNR (Order Number) field, which is char(12).
    >
    > The problem I'm having is this:  All of the values in AUFNR are preceeded by two zeros.  For example, if I have a MEASURE value of '5200000017', the corresponding value in AUFNR is '005200000017'.  Because I have my SQL statement coded to just match the two fields, I obviously get no records returned because, I assume, of those leading zeros.
    > Dave
    You can't do a join like this in SAP's open SQL.  You could do it in real SQL ie EXEC.... ENDEXEC by using SUSBTR to strip off the leading zeros from AUFNR but this would not be a good idea because a)  modifying a column in the WHERE clause will stop any index on that column being used and b) using real SQL rather than open SQL is really not something that should be encouraged for database portability reasons etc. 
    Forget about a database join and do it in two stages; get your AUFK data into an itab, strip off the leading zeros, and then use FAE to get the FMIFIIT data (or do it the other way round). 
    I do hope you've got an index on your FMIFIIT MEASURE field (we don't have one here); otherwise your SELECT could be slow if the table holds a lot of data.

  • How to write this sql query in php code ?

    for example:
    insert into temp
    select *
    from testtable;
    after this, i will query data from sql below:
    select *
    from temp;
    how to write this php code ?
    who can help me ?
    thanks!

    Have a look at the manual to find out how to issue queries.
    http://us3.php.net/oci8

  • How to tune this SQL?

    What this SQL did is to generate a report like how many rows for each tp_stts when ims_toms_msge_type='TOMS NEW' (or 'TOMS CNCLO'). also, its corresponding total number for each ims_toms_msge_type.
    Here is the sample:
    Rownum    H1            TP_STTS                          COUNT        IMS_TOMS_MSGE_TYPE    H   FILTERTYPE
    1     Trades     Block Key Data Error                      594           TOMS NEW             A     MSL
    2          Allocation Data Error                      334           TOMS NEW             A     MSL
    3          Manual Processing Required                29           TOMS NEW             A      MSL
    4          Manual Removal No Processing Required     67           TOMS NEW             A      MSL
    5          Waiting For Authorization                 2            TOMS NEW             A     MSL
    6           Auto NAK                             19764          TOMS NEW             B     SLS
    7           Validated                             165023         TOMS NEW             B     SLS
    8     GRAND TOTAL                                    185813          TOMS NEW              H     MSL
    9     Cancel     Auto NAK                              37             TOMS CNCLO        X       MSL
    10          Manual Processing Required   114                    TOMS CNCLO          X      MSL
    11          Manually Processed              278                   TOMS CNCLO     X     MSL
    12     CANCEL GRAND TOTAL                        429                TOMS CNCLO           Z      MSLSQL statement as below:
    SELECT ROWNUM, MSGS.* FROM (with FTMReport as (
           select tp_stts, ims_toms_msge_type, count(*) count  from ims_trde, ims_toms_msge
                    where  ( IMS_TRDE.PRCSG_GRP_ID  = 5  )  AND  ( IMS_TRDE.IMS_TRDE_RCPT_DTTM  >= TO_DATE('12/01/2009 00:00', 'MM/DD/YYYY HH24:MI') AND IMS_TRDE.IMS_TRDE_RCPT_DTTM <= (TO_DATE('12/28/2009 23:59', 'MM/DD/YYYY HH24:MI'))  )  AND (IMS_TRDE.GRS_TRX_TYPE NOT IN ('INJECTION','WITHDRAWAL','PAYMENT') OR IMS_TRDE.GRS_TRX_TYPE IS NULL) AND (IMS_TRDE.SSC_INVST_TYPE != 'FC' OR IMS_TRDE.SSC_INVST_TYPE IS NULL) AND (IMS_TRDE.SERVICE_TYPE='FS' OR IMS_TRDE.SERVICE_TYPE='CO')  AND 1=1 
        and IMS_TRDE.SERVICE_TYPE='FS'    and  1=1  and ims_trde.ims_trde_oid = ims_toms_msge.ims_trde_oid
           group by tp_stts, ims_toms_msge_type
          select 'GRAND TOTAL' H1,  null tp_stts, sum(Count) count , ims_toms_msge_type ,'H', 'MSL' FilterType
                   from FTMReport  where  ims_toms_msge_type in ('TOMS NEW') group by ims_toms_msge_type
        union
          select 'CANCEL GRAND TOTAL' H1,  null tp_stts, sum(Count) count, ims_toms_msge_type ,'Z', 'MSL' FilterType 
                   from FTMReport where  ims_toms_msge_type in ('TOMS CNCLO') group by ims_toms_msge_type
        union
          select DECODE(rownum, 1, 'Trades') H1, tp_stts, count, ims_toms_msge_type , 'A' , 'MSL' FilterType
                   from FTMReport  where  ims_toms_msge_type in ('TOMS NEW') and tp_stts not in ('Validated','Auto NAK','Manual NAK')
        union
          select ' ' H1, tp_stts, count, ims_toms_msge_type , 'B' , 'SLS' FilterType
                   from FTMReport where  ims_toms_msge_type in ('TOMS NEW') and tp_stts in ('Validated','Auto NAK','Manual NAK')
        union
          select DECODE(rownum, 1, 'Cancel') H1, tp_stts, count, ims_toms_msge_type , 'X' , 'MSL' FilterType
                   from FTMReport where  ims_toms_msge_type in ('TOMS CNCLO') order by 5,6
        ) MSGS;Explain plan as below:
    | Id  | Operation                           |  Name                        | Rows  | Bytes | Cost  |
    |   0 | SELECT STATEMENT                    |                              |   193 | 12738 |    32 |
    |   1 |  COUNT                              |                              |       |       |       |
    |   2 |   VIEW                              |                              |   193 | 12738 |    32 |
    |   4 |    TEMP TABLE TRANSFORMATION        |                              |       |       |       |
    |   3 |     RECURSIVE EXECUTION             | SYS_LE_4_0                   |       |       |       |
    |   0 |      INSERT STATEMENT               |                              |    61 |  4575 |  9264 |
    |   1 |       LOAD AS SELECT                |                              |       |       |       |
    |   2 |        SORT GROUP BY                |                              |    61 |  4575 |  9264 |
    |   3 |         NESTED LOOPS                |                              |  1604 |   117K|  9251 |
    |*  4 |          TABLE ACCESS BY INDEX ROWID| IMS_TRDE                     |  1603 | 80150 |  6045 |
    |*  5 |           INDEX RANGE SCAN          | IMS_TRDE_INDX4               |   539K|       |  3917 |
    |*  6 |          INDEX RANGE SCAN           | IMS_TOMS_MSGE_INDX1          |     1 |    25 |     2 |
    |   5 |     SORT UNIQUE                     |                              |   193 |  8831 |    30 |
    |   6 |      UNION-ALL                      |                              |       |       |       |
    |   7 |       SORT GROUP BY NOSORT          |                              |     5 |   115 |     6 |
    |*  8 |        VIEW                         |                              |    61 |  1403 |     2 |
    |   9 |         TABLE ACCESS FULL           | SYS_TEMP_0FD9D660F_B198D56F  |    61 |  2074 |     2 |
    |  10 |       SORT GROUP BY NOSORT          |                              |     5 |   115 |     6 |
    |* 11 |        VIEW                         |                              |    61 |  1403 |     2 |
    |  12 |         TABLE ACCESS FULL           | SYS_TEMP_0FD9D660F_B198D56F  |    61 |  2074 |     2 |
    |  13 |       COUNT                         |                              |       |       |       |
    |* 14 |        VIEW                         |                              |    61 |  2867 |     2 |
    |  15 |         TABLE ACCESS FULL           | SYS_TEMP_0FD9D660F_B198D56F  |    61 |  2074 |     2 |
    |* 16 |       VIEW                          |                              |    61 |  2867 |     2 |
    |  17 |        TABLE ACCESS FULL            | SYS_TEMP_0FD9D660F_B198D56F  |    61 |  2074 |     2 |
    |  18 |       COUNT                         |                              |       |       |       |
    |* 19 |        VIEW                         |                              |    61 |  2867 |     2 |
    |  20 |         TABLE ACCESS FULL           | SYS_TEMP_0FD9D660F_B198D56F  |    61 |  2074 |     2 |
    Predicate Information (identified by operation id):
       4 - filter(("IMS_TRDE"."GRS_TRX_TYPE"<>'INJECTION' AND "IMS_TRDE"."GRS_TRX_TYPE"<>'WITHDRAWAL'
                  AND "IMS_TRDE"."GRS_TRX_TYPE"<>'PAYMENT' OR "IMS_TRDE"."GRS_TRX_TYPE" IS NULL) AND
                  ("IMS_TRDE"."SSC_INVST_TYPE"<>'FC' OR "IMS_TRDE"."SSC_INVST_TYPE" IS NULL))
       5 - access("IMS_TRDE"."IMS_TRDE_RCPT_DTTM">=TO_DATE(' 2009-12-01 00:00:00', 'syyyy-mm-dd
                  hh24:mi:ss') AND "IMS_TRDE"."PRCSG_GRP_ID"=5 AND "IMS_TRDE"."SERVICE_TYPE"='FS' AND
                  "IMS_TRDE"."IMS_TRDE_RCPT_DTTM"<=TO_DATE(' 2009-12-28 23:59:00', 'syyyy-mm-dd hh24:mi:ss'))
           filter("IMS_TRDE"."PRCSG_GRP_ID"=5 AND "IMS_TRDE"."SERVICE_TYPE"='FS')
       6 - access("IMS_TRDE"."IMS_TRDE_OID"="IMS_TOMS_MSGE"."IMS_TRDE_OID")
       8 - filter("FTMREPORT"."IMS_TOMS_MSGE_TYPE"='TOMS NEW')
      11 - filter("FTMREPORT"."IMS_TOMS_MSGE_TYPE"='TOMS CNCLO')
      14 - filter("FTMREPORT"."IMS_TOMS_MSGE_TYPE"='TOMS NEW' AND "FTMREPORT"."TP_STTS"<>'Validated'
                  AND "FTMREPORT"."TP_STTS"<>'Auto NAK' AND "FTMREPORT"."TP_STTS"<>'Manual NAK')
      16 - filter("FTMREPORT"."IMS_TOMS_MSGE_TYPE"='TOMS NEW' AND ("FTMREPORT"."TP_STTS"='Auto NAK' OR
                  "FTMREPORT"."TP_STTS"='Manual NAK' OR "FTMREPORT"."TP_STTS"='Validated'))
      19 - filter("FTMREPORT"."IMS_TOMS_MSGE_TYPE"='TOMS CNCLO')
    Note: cpu costing is offCould you guys tell me what is wrong with this sql and how to tune it?
    Is there any way to replace the UNION? Is using UNION a good idea?
    Can I use DECODE or CASE WHEN to simplify it? How?
    Also, could you help explain why there is SYS_LE_4_0, SYS_TEMP_0FD9D660F_B198D56F temporary segment? Is it caused by with FTMReport as ?
    Thanks
    Edited by: PhoenixBai on Dec 31, 2009 9:58 AM
    Edited by: PhoenixBai on Dec 31, 2009 12:08 PM
    Edited by: PhoenixBai on Dec 31, 2009 12:17 PM

    I consider using GROUP BY ROLLUP together with DECODE, CASE WHEN, but haven`t come out with a working sql yet:-(Some sample data to work with would have been much helpful. But we dont get that most of the time :(
    I came up with this.
                    select case when ims_toms_msge_type = 'TOMS NEW' then
                                     case when grouping(tp_stts) = 1 then 'GRAND TOTAL'
                                          when tp_stts not in ('Validated','Auto NAK','Manual NAK') then 'Trades'
                                     end
                                when ims_toms_msge_type = 'TOMS CNCLO' then
                                     case when grouping(tp_stts) = 1 then 'CANCEL GRAND TOTAL'
                                          when tp_stts in ('Validated','Auto NAK','Manual NAK') then 'Cancel'
                                     end
                           end h1,
                           tp_stts,
                           count(*) count,
                           ims_toms_msge_type,
                           case when ims_toms_msge_type = 'TOMS NEW' then
                                     case when grouping(tp_stts) = 1 then 'H'
                                          when tp_stts not in ('Validated','Auto NAK','Manual NAK') then 'A'
                                     end
                                when ims_toms_msge_type = 'TOMS CNCLO' then
                                     case when grouping(tp_stts) = 1 then 'Z'
                                          when tp_stts in ('Validated','Auto NAK','Manual NAK') then 'B'
                                     end
                           end flag,
                           'MSL' FilterType
                   from ims_trde,
                        ims_toms_msge
                     where IMS_TRDE.PRCSG_GRP_ID  = 5 
                       AND IMS_TRDE.IMS_TRDE_RCPT_DTTM  >= TO_DATE('12/01/2009 00:00', 'MM/DD/YYYY HH24:MI')
                       AND IMS_TRDE.IMS_TRDE_RCPT_DTTM <=  TO_DATE('12/28/2009 23:59', 'MM/DD/YYYY HH24:MI') 
                       AND (IMS_TRDE.GRS_TRX_TYPE NOT IN ('INJECTION','WITHDRAWAL','PAYMENT')
                        OR IMS_TRDE.GRS_TRX_TYPE IS NULL)
                       AND (IMS_TRDE.SSC_INVST_TYPE != 'FC'
                        OR IMS_TRDE.SSC_INVST_TYPE IS NULL)
                       AND (IMS_TRDE.SERVICE_TYPE = 'FS'
                        OR IMS_TRDE.SERVICE_TYPE = 'CO')
                       AND 1=1 
                     and IMS_TRDE.SERVICE_TYPE = 'FS'   
                     and  1=1 
                     and ims_trde.ims_trde_oid = ims_toms_msge.ims_trde_oid
                      group by rollup(ims_toms_msge_type, tp_stts)Not sure if this code works. Because i dint have the table or the data to test it. So if it has some error just fix it and give it a try. Do post the kind of output it gives. So that we can see if we can work with this solution.

  • How to rewrite this SQL statement

    I have tableA and tableB as below. The following query gets Max(Process_date) during month of january from the
    two tables tableA and tableB with different criteria
    I want to expand the following query to return  Max(Process_date) for BOTH current month(txn_date=entire jan2013) and prior month(txn_date= entire dec2013)
    Is it possible? If so how can I modify this query to return MAX(PROCESS_DATE) for current and prior months in single query.
    SELECT MAX(process_date)  AS curr_month_amount FROM
      SELECT process_date AS process_date,
             amount1 AS amount
      FROM   tableA
      WHERE  id = 1 AND
             process_date = (SELECT MAX(process_date)
                      FROM tableA
                     WHERE id = 1  and txn_date between TO_DATE('01-JAN-2013','dd-mon-yyyy') and TO_DATE('31-JAN-2013', 'dd-mon-yyyy')
            AND amount1 = 0
          UNION
      SELECT MAX(process_date) AS process_date,
             0 AS amount
      FROM   tableB
      WHERE id = 1 AND txn_code = 'B' and  txn_date between TO_DATE('01-JAN-2013','dd-mon-yyyy') and TO_DATE('31-JAN-2013', 'dd-mon-yyyy')
    future state of the sql
    Single sql statement a) should look at txn_date between 1/1/2013 - 1/31/2013 to return max(process_date) for current month
                         b) should look at txn_date between 12/1/2012 - 12/31/2012 to return max(process_date) for prior month
    NOTE:-( i want to pass current_month_end date 1/31/2013 to this sql so it will calculate for current and prior months)
    expected output
    ***************:   For id=1 in the modified query,
       prior month max(process_date) should be    1/19/2013
       current month max(process_date) should be   1/15/2012
         For id=5 in the modified query
       prior month max(process_date) should be   NULL
       current month max(process_date) should be  1/16/2013
    SQL to create TableA and TableB  with insert statements( txn_date column not included)
    CREATE table tableA
    id   NUMBER,
    process_date  DATE,
    amount1         NUMBER,
    txn_code VARCHAR2(1),
    txn_date DATE
    Create table tableB
    ( id  NUMBER,
    process_date DATE,
    amount2         NUMBER,
    txn_code VARCHAR2(1),
    txn_date DATE
    INSERT INTO tableA
    ( id, process_date, amount1, txn_code, txn_date )
    values
    ( 1, to_date('01/12/2013','mm/dd/yyyy'), 500, 'A',  to_date('01/15/2013','mm/dd/yyyy')  );
    INSERT INTO tableA
    ( id, process_date, amount1, txn_code, txn_date )
    values
    ( 1, to_date('01/13/2013','mm/dd/yyyy'), 100, 'A',  to_date('01/14/2013','mm/dd/yyyy'));
    INSERT INTO tableA
    ( id, process_date, amount1, txn_code , txn_date)
    values
    ( 1, to_date('01/14/2013','mm/dd/yyyy'), 0, 'A',    to_date('01/15/2013','mm/dd/yyyy'));  
    INSERT INTO tableB
    ( id, process_date, amount2, txn_code, txn_date)
    values
    ( 1, to_date('01/15/2013','mm/dd/yyyy'), 0, 'B', to_date('01/31/2013','mm/dd/yyyy'));
    INSERT INTO tableA
    ( id, process_date, amount1, txn_code, txn_date )
    values
    ( 1, to_date('12/01/2012','mm/dd/yyyy'), 500, 'A',  to_date('12/31/2012','mm/dd/yyyy')  );
    INSERT INTO tableA
    ( id, process_date, amount1, txn_code , txn_date)
    values
    ( 1, to_date('12/23/2012','mm/dd/yyyy'), 100, 'A',  to_date('12/14/2012','mm/dd/yyyy'));
    INSERT INTO tableA
    ( id, process_date, amount1, txn_code, txn_date )
    values
    ( 1, to_date('12/19/2012','mm/dd/yyyy'), 0, 'A',    to_date('12/15/2012','mm/dd/yyyy'));  
    INSERT INTO tableB
    ( id, process_date, amount2, txn_code, txn_date)
    values
    ( 1, to_date('12/15/2012','mm/dd/yyyy'), 0, 'C', to_date('12/31/2012','mm/dd/yyyy'));
    INSERT INTO tableA
    ( id, process_date, amount1, txn_code, txn_date )
    values
    ( 5, to_date('01/11/2013','mm/dd/yyyy'), 500, 'A', to_date('01/09/2013','mm/dd/yyyy')    );
    INSERT INTO tableA
    ( id, process_date, amount1, txn_code, txn_date )
    values
    (5, to_date('01/12/2013','mm/dd/yyyy'), 0, 'A', to_date('01/19/2013','mm/dd/yyyy'))
    INSERT INTO tableA
    ( id, process_date, amount1, txn_code, txn_date )
    values
    ( 5, to_date('01/15/2013','mm/dd/yyyy'), 10 , 'A', to_date('01/09/2013','mm/dd/yyyy'));  
    INSERT INTO tableB
    ( id, process_date, amount2, txn_code, txn_date)
    values
    ( 5, to_date('01/16/2013','mm/dd/yyyy'), 1, 'B', to_date('01/09/2013','mm/dd/yyyy'));
    INSERT INTO tableA
    ( id, process_date, amount1, txn_code, txn_date )
    values
    ( 5, to_date('12/11/2012','mm/dd/yyyy'), 500, 'A', to_date('12/09/2012','mm/dd/yyyy')    );
    INSERT INTO tableA
    ( id, process_date, amount1, txn_code, txn_date )
    values
    (5, to_date('12/12/2012','mm/dd/yyyy'), 0, 'A', to_date('12/19/2012','mm/dd/yyyy'))
    INSERT INTO tableA
    ( id, process_date, amount1, txn_code, txn_date )
    values
    ( 5, to_date('12/15/2012','mm/dd/yyyy'), 10 , 'A', to_date('12/09/2012','mm/dd/yyyy'));  
    INSERT INTO tableB
    ( id, process_date, amount2, txn_code, txn_date)
    values
    ( 5, to_date('12/16/2012','mm/dd/yyyy'), 1, 'C', to_date('12/09/2012','mm/dd/yyyy'));
    commit;

    Maybe
    SELECT id,
           month,
           MAX(process_date) AS curr_month_amount
      FROM (SELECT id,
                   process_date AS process_date,
                   amount1 AS amount,
                   TO_CHAR(txn_date,'mm') AS month
              FROM tableA
             WHERE (process_date,TO_CHAR(txn_date,'mm')) in
                     (SELECT MAX(process_date),TO_CHAR(txn_date,'mm') 
                        FROM tableA
                       WHERE txn_date between ADD_MONTHS(TO_DATE('01-JAN-2013','dd-mon-yyyy'),-1)
                                          AND TO_DATE('31-JAN-2013','dd-mon-yyyy')
                         AND amount1 = 0
                       GROUP BY TO_CHAR(txn_date,'mm')
               AND amount1 = 0
            UNION
            SELECT id,
                   MAX(process_date) AS process_date,
                   0 AS amount,
                   TO_CHAR(txn_date,'mm') AS month
              FROM tableB
             WHERE txn_code = 'B'
               AND txn_date between ADD_MONTHS(TO_DATE('01-JAN-2013','dd-mon-yyyy'),-1)
                                AND TO_DATE('31-JAN-2013','dd-mon-yyyy')
             GROUP BY id,TO_CHAR(txn_date,'mm')
    GROUP BY id,month
    ID
    MONTH
    CURR_MONTH_AMOUNT
    5
    01
    01/16/2013
    1
    12
    12/19/2012
    1
    01
    01/15/2013
    Regards
    Etbin

  • Can you optimize this sql?

    Hi,
    I believe that this sql can be improved, but honestly i don't know how.
                   Select * From Ctb_Mov m Where m.CodEmp = 1 and m.Plano='G' and
                   Cg Between '211' and '211'
                   and cx between '1' and '9999999'
                   and (M.GRUPO is NULL or
                  M.GRUPO in (select m1.GRUPO
                                        from ctb_mov M1
                                        where M1.CODEMP = m.codemp and
                                                  M1.PLANO = m.plano and
                                                  M1.cg = M.cg and
                                                  M1.cx = M.cx and
                                                  M1.GRUPO = M.GRUPO and
                                                  M1.datamov <= to_date('17092009','ddmmyyyy') and
                                                  M1.GRUPO <> 9999999
                                        group by M1.CODEMP, M1.PLANO, M1.cg,
                                                      M1.CX, M1.GRUPO
                                        having sum(M1.VLD - M1.VLC) <> 0))
    Suggestions?
    Regards
    Jomar

    [HOW TO: Post a SQL statement tuning request - template posting |http://forums.oracle.com/forums/thread.jspa?threadID=863295&tstart=0]
    This thread will give a good insight on how to ask a performance tuning question in this forum. Following that will get you good answers!!

  • Performance Tuning Issues  ( How to Optimize this Code)

    _How to Optimize this Code_
    FORM MATL_CODE_DESC.
      SELECT * FROM VBAK WHERE VKORG EQ SAL_ORG AND
                               VBELN IN VBELN AND
                               VTWEG IN DIS_CHN AND
                               SPART IN DIVISION AND
                               VKBUR IN SAL_OFF AND
                               VBTYP EQ 'C' AND
                               KUNNR IN KUNNR AND
                               ERDAT BETWEEN DAT_FROM AND DAT_TO.
        SELECT * FROM VBAP WHERE VBELN EQ VBAK-VBELN AND
                                 MATNR IN MATNR.
          SELECT SINGLE * FROM MAKT WHERE MATNR EQ VBAP-MATNR.
          IF SY-SUBRC EQ 0.
            IF ( VBAP-NETWR EQ 0 AND VBAP-UEPOS NE 0 ).
              IF ( VBAP-UEPVW NE 'B' AND VBAP-UEPVW NE 'C' ).
                MOVE VBAP-VBELN TO ITAB1-SAL_ORD_NUM.
                MOVE VBAP-POSNR TO ITAB1-POSNR.
                MOVE VBAP-MATNR TO ITAB1-FREE_MATL.
                MOVE VBAP-KWMENG TO ITAB1-FREE_QTY.
                MOVE VBAP-KLMENG TO ITAB1-KLMENG.
                MOVE VBAP-VRKME TO ITAB1-FREE_UNIT.
                MOVE VBAP-WAVWR TO ITAB1-FREE_VALUE.
                MOVE VBAK-VTWEG TO ITAB1-VTWEG.
                MOVE VBAP-UEPOS TO ITAB1-UEPOS.
              ENDIF.
            ELSE.
              MOVE VBAK-VBELN TO ITAB1-SAL_ORD_NUM.
              MOVE VBAK-VTWEG TO ITAB1-VTWEG.
              MOVE VBAK-ERDAT TO ITAB1-SAL_ORD_DATE.
              MOVE VBAK-KUNNR TO ITAB1-CUST_NUM.
              MOVE VBAK-KNUMV TO ITAB1-KNUMV.
             SELECT SINGLE * FROM KONV WHERE KNUMV EQ VBAK-KNUMV AND
                                             KSTEU = 'C' AND
                                             KHERK EQ 'A' AND
                                             KMPRS = 'X'.
             IF SY-SUBRC EQ 0.
               ITAB1-REMARKS = 'Manual Price Change'.
             ENDIF.
              SELECT SINGLE * FROM KONV WHERE KNUMV EQ VBAK-KNUMV AND
                                              KSTEU = 'C' AND
                                              KHERK IN ('C','D') AND
                                              KMPRS = 'X' AND
                                              KRECH IN ('A','B').
              IF SY-SUBRC EQ 0.
                IF KONV-KRECH EQ 'A'.
                  MOVE : KONV-KSCHL TO G_KSCHL.
                  G_KBETR = ( KONV-KBETR / 10 ).
                  MOVE G_KBETR TO G_KBETR1.
                  CONCATENATE G_KSCHL G_KBETR1 '%'
                              INTO ITAB1-REMARKS SEPARATED BY SPACE.
                ELSEIF KONV-KRECH EQ 'B'.
                  MOVE : KONV-KSCHL TO G_KSCHL.
                  G_KBETR = KONV-KBETR.
                  MOVE G_KBETR TO G_KBETR1.
                  CONCATENATE G_KSCHL G_KBETR1
                              INTO ITAB1-REMARKS SEPARATED BY SPACE.
                ENDIF.
              ELSE.
                ITAB1-REMARKS = 'Manual Price Change'.
              ENDIF.
              CLEAR : G_KBETR, G_KSCHL,G_KBETR1.
              MOVE VBAP-KWMENG TO ITAB1-QTY.
              MOVE VBAP-VRKME TO ITAB1-QTY_UNIT.
              IF VBAP-UMVKN NE 0.
                ITAB1-KLMENG = ( VBAP-UMVKZ / VBAP-UMVKN ) * VBAP-KWMENG.
              ENDIF.
              IF ITAB1-KLMENG NE 0.
                VBAP-NETWR = ( VBAP-NETWR / VBAP-KWMENG ).
                MOVE VBAP-NETWR TO ITAB1-INV_PRICE.
              ENDIF.
              MOVE VBAP-POSNR TO ITAB1-POSNR.
              MOVE VBAP-MATNR TO ITAB1-MATNR.
              MOVE MAKT-MAKTX TO ITAB1-MAKTX.
            ENDIF.
            SELECT SINGLE * FROM VBKD WHERE VBELN EQ VBAK-VBELN AND
                                            BSARK NE 'DFUE'.
            IF SY-SUBRC EQ 0.
              ITAB1-INV_PRICE = ITAB1-INV_PRICE * VBKD-KURSK.
              APPEND ITAB1.
              CLEAR ITAB1.
            ELSE.
              CLEAR ITAB1.
            ENDIF.
          ENDIF.
        ENDSELECT.
      ENDSELECT.
    ENDFORM.                               " MATL_CODE_DESC

    Hi Vijay,
    You could start by using INNER JOINS:
    SELECT ......
                FROM (                    VBAK
                             INNER JOIN VBAP
                                           ON VBAPVBELN = VBAKVBELN
                             INNER JOIN MAKT
                                           ON MAKTMATNR = VBAPMATNR AND
                                                 MAKT~SPRAS = SYST-LANGU )
                INTO TABLE itab
              WHERE VBAK~VBELN IN VBELN
                   AND VBAK~VTWEG IN DIS_CHN
                   AND VBAK~SPART IN DIVISION
                   AND VBAK~VKBUR IN SAL_OFF
                   AND VBAK~VBTYP EQ 'C'
                   AND VBAK~KUNNR IN KUNNR
                   AND VBAK~ERDAT BETWEEN DAT_FROM AND DAT_TO
                   AND VBAP~NETWR EQ 0
                   AND VBAP~UEPOS NE 0
    Regards,
    John.

Maybe you are looking for