IN operator in Where Clause

Hi Experts,
I have been facing a problem in passing multiple values to the where clause in select query. I have 15 values in which i need to check in where condition.
Ex:  SELECT AMATNR ASPART
           INTO TABLE IT_DIVISION
           FROM MARA AS A
           INNER JOIN MARC AS B ON
           AMATNR = BMATNR
           FOR ALL ENTRIES IN IT_UPDATE
           WHERE A~MATNR EQ IT_UPDATE-MATNR
           AND A~MTART IN ('ZLHA', 'ZFER', 'ZHAL', 'ZNLA', 'ZOPS',
                           'ZPSE', 'ZROH', 'ZUNB', 'ZVER ', 'ZDIA').
Now i need to include some more (5) values, but its showing some error.
Please guide me in this.
Thnx in Adv..Meher

Hi,
Make use of a range table.
types : begin of T_range,
sign type TVARV_SIGN,
option type TVARV_OPTI,
low type mtart,
high type mtart,
end of t_range.
data: IT_RANGE type standard table of T_range.
data : wa_range type T_RANGe.
wa_range-sign = 'I'.
wa_range-option = 'EQ'.
wa_range-low = 'ZLHA'
append wa_range to IT_RANGE.
wa_range-sign = 'I'.
wa_range-option = 'EQ'.
wa_range-low = 'ZFER'
append wa_range to IT_RANGE.
wa_range-sign = 'I'.
wa_range-option = 'EQ'.
wa_range-low = 'ZHAL'
append wa_range to IT_RANGE.
and so on till all your values are filled in the table and then use this table in the IN clause.
SELECT AMATNR ASPART
INTO TABLE IT_DIVISION
FROM MARA AS A
INNER JOIN MARC AS B ON
AMATNR = BMATNR
FOR ALL ENTRIES IN IT_UPDATE
WHERE A~MATNR EQ IT_UPDATE-MATNR
AND A~MTART IN it_range.
The error which you are getting is because of the spacing between the different MTART values which you have included in the bracket.
After every comma there should be a space.
But you should always use range for such requirements.
regards,
Ankur Parab
Edited by: Ankur Parab on Jun 23, 2009 6:59 PM

Similar Messages

  • AND and OR operations in WHERE clause

    Hello, Dear Oracle professionals.
    In WHERE clause when I use AND or OR operations, is there any way of working ORACLE server to select rows?
    For example
    WHERE con1 and con2 and con3 and con4 and con5OR
    WHERE con1 or con2 or con3 or con4 or con5How oracle checks this conditions ? From the begining to the end ? in order ?
    May be I should put some more probable TRUE condition to the end(or to the begin).
    Whant to know how oracle thinks.
    Thanks in advance.

    Hi,
    Khayyam wrote:
    Hello, Dear Oracle professionals.
    In WHERE clause when I use AND or OR operations, is there any way of working ORACLE server to select rows?
    For example
    WHERE con1 and con2 and con3 and con4 and con5OR
    WHERE con1 or con2 or con3 or con4 or con5How oracle checks this conditions ? From the begining to the end ? in order ?It evalauates the one that is likely to make the most difference first. In the case of AND, that means the condition that is least likely to be true (as far as the optimizer can predict).
    May be I should put some more probable TRUE condition to the end(or to the begin).It doesn't matter to the optimizer. Do whatever you find easier to read and debug.
    In ancient times, using the rule-based optimizer, order did matter, but there's no reason to be using the rule-based optimizer now. Oracle 11 doesn't even have the option.
    By the way, be careful not to mix AND and OR without parentheses. That is, never say:
    WHERE  x AND y OR z    -- ***** No!  Wrong!  ******Instead say
    WHERE  (x AND y) OR z   or
    WHERE  x AND (y OR z)   depending on what you want. If you don't use partentheses, then there are rules about how the expresssion is evaluated, but it's a waste of your time to learn them.

  • Invalid relational operator in where clause dynamic

    I have a procedure where I pass the WHERE CLAUSE as a parameter like this:
    PROCEDURE PRC_CONSULTAR_AFIL_PEND(PV_WHERE IN VARCHAR2,
    RESULTSETM IN OUT SYS_REFCURSOR)
    IS
    BEGIN
    OPEN RESULTSETM FOR
    'SELECT PAISAFIL,
    TIPDOCAFIL,
    NUMDOCAFIL,
    APPAFIL,
    APMAFIL,
    NOMAFIL,
    SEXAFIL,
    FECNACAFIL,
    CODPNA,
    ESTADO,
    FECHA,
    TO_DATE(FECGEN),
    NOMCOLUMN
    FROM SUNAFILERR
    WHERE ' || PV_WHERE;
    I am passing the where clause as: 'APPAFIL'||' '||'APMAFIL'||' '||'NOMAFIL LIKE UPPER(rojas%)'

    Miguel Angel wrote:
    I have a procedure where I pass the WHERE CLAUSE as a parameter like this:
    PROCEDURE PRC_CONSULTAR_AFIL_PEND(PV_WHERE IN VARCHAR2,
    RESULTSETM IN OUT SYS_REFCURSOR)
    IS
    BEGIN
    OPEN RESULTSETM FOR
    'SELECT PAISAFIL,
    TIPDOCAFIL,
    NUMDOCAFIL,
    APPAFIL,
    APMAFIL,
    NOMAFIL,
    SEXAFIL,
    FECNACAFIL,
    CODPNA,
    ESTADO,
    FECHA,
    TO_DATE(FECGEN),
    NOMCOLUMN
    FROM SUNAFILERR
    WHERE ' || PV_WHERE;
    I am passing the where clause as: 'APPAFIL'||' '||'APMAFIL'||' '||'NOMAFIL LIKE UPPER(rojas%)'So your where clause is
    WHERE APPAFIL APMAFIL NOMAFIL LIKE UPPER (rojas%)Can you see why that's an error? It would make more sense if there was an operator between APPAFIL and APMAFIL, but then there's obviously something missing between APMAFIL and NOMAFIL as well, and some quotes missing later on.
    The following is valid SQL code
    WHERE   APPAFIL  != APMAFIL
    AND     NOMAFIL  LIKE UPPER ('rojas%')Of course, I have no idea if that's what you want or not.
    Whenever you have a problem, please post a little sample data (CREATE TABLE and INSERT statements) for any tables used, and the results you want from that data.
    if the problem involves parameters (such as the pv_where), then post a couple of different parameters, and the results you want from the same sample data for each parameter.
    Explain how you get those results from that parameter and that data.
    Always say which version of Oracle you're using.

  • How to use string operation in where clause of select query

    Hello All,
    I just want to know how can i write a restriction in select query saying retrive data only begins with name "DE*".
    Explaination: If my table has records and names starts with character then i want to write a query to fetch all the records in which names starts with DE*.
    Thanks in advance for your quick reply...
    Dev.

    Hi
    In the where clause you need to write like
    WHERE NAME LIKE 'DE%'
    Regards
    Sudheer

  • Conditional operator in where clause?

    I have 4 assignable parameters for filtering records. If a parameter is not assigned the filter is ignored. This is working fine with the SQL-statement below except for one scenario: if none of the parameters are assigned I get no records at all but then I need all of the records.
    with t as
        select 1 as val, 'a' as var from dual union all
        select 2 as val, 'a' as var from dual union all
        select 3 as val, 'b' as var from dual union all
        select 4 as val, 'b' as var from dual union all
        select 5 as val, 'b' as var from dual union all
        select 6 as val, 'c' as var from dual union all
        select 7 as val, 'd' as var from dual union all
        select 8 as val, 'e' as var from dual union all
        select 9 as val, 'e' as var from dual union all
        select 0 as val, 'f' as var from dual
    select *
    from t
    where t.var = decode(:pvar1,'',null,:pvar1)
    or t.var = decode(:pvar2,'',null,:pvar2)
    or t.var = decode(:pvar3,'',null,:pvar3)
    or t.var = decode(:pvar4,'',null,:pvar4)

    You need no "OR"s
    <br>
    SQL> var pvar1 char
    SQL> var pvar2 char
    SQL> var pvar3 char
    SQL> var pvar4 char
    SQL> with t as(    select 1 as val, 'a' as var from dual union all
      2      select 2 as val, 'a' as var from dual union all
      3      select 3 as val, 'b' as var from dual union all
      4      select 4 as val, 'b' as var from dual union all
      5      select 5 as val, 'b' as var from dual union all
      6      select 6 as val, 'c' as var from dual union all
      7      select 7 as val, 'd' as var from dual union all
      8      select 8 as val, 'e' as var from dual union all
      9      select 9 as val, 'e' as var from dual union all
    10      select 0 as val, 'f' as var from dual)
    11  select *from t
    12  where t.var = coalesce(:pvar1,:pvar2,:pvar3,:pvar4,t.var);
           VAL V
             1 a
             2 a
             3 b
             4 b
             5 b
             6 c
             7 d
             8 e
             9 e
             0 f
    10 rows selected.
    SQL> exec :pvar4 := 'b';
    PL/SQL procedure successfully completed.
    SQL>  with t as(    select 1 as val, 'a' as var from dual union all
      2       select 2 as val, 'a' as var from dual union all
      3       select 3 as val, 'b' as var from dual union all
      4       select 4 as val, 'b' as var from dual union all
      5       select 5 as val, 'b' as var from dual union all
      6       select 6 as val, 'c' as var from dual union all
      7       select 7 as val, 'd' as var from dual union all
      8       select 8 as val, 'e' as var from dual union all
      9       select 9 as val, 'e' as var from dual union all
    10       select 0 as val, 'f' as var from dual)
    11   select *from t
    12   where t.var = coalesce(:pvar1,:pvar2,:pvar3,:pvar4,t.var);
           VAL V
             3 b
             4 b
             5 b
    Message was edited by:
            jeneesh
    I did mistake. Follow Dave's post                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • Using regexp_instr in a where clause - invalid relational operator

    Whey I try to run this query in TOAD I get an ORA-00920: invalid relational operator error. It's part of a 10g stored procedure. When I highlight it and run it it prompts me for the missing values and then the error pops up. The AND in line 4 is highlighted.
    select CRIME_CLASSIFICATION_ID, crime_type, nvl(count(CRIME_CLASSIFICATION_ID),0) as CRIMECNT
    From vaps.vw_offenses
        where  regexp_instr(valoc,to_char(location_id))
            AND ( fromdate is null or
             offense_date between to_date(fromdate, 'mm/dd/yyyy')  AND to_date(todate,'mm/dd/yyyy')
    group by crime_classification_id, crime_type

    Hi,
    Review what REGEXP_INSTR does: it returns a NUMBER.
    Your WHERE clause couldn't make any sense if you used any other kind of NUMBER expression in that place, e.g. a NUMBER literal such as 12:
    select CRIME_CLASSIFICATION_ID, crime_type, nvl(count(CRIME_CLASSIFICATION_ID),0) as CRIMECNT
    From vaps.vw_offenses
        where  12     -- This is obviously wrong
            AND ( fromdate is null or
             offense_date between to_date(fromdate, 'mm/dd/yyyy')  AND to_date(todate,'mm/dd/yyyy')
    group by crime_classification_id, crime_type
    It's not going to work any better with a function (like REGEXP_INSTR) that returns a NUMBER.
    How can you fix it?  That depends on what you want to do.  Why are you calling REGEXP_INSTR?  What is that condition checking?
    Whenever you have a problem, please post a little sample data (CREATE TABLE and INSERT statements, relevant columns only) from all tables involved, so that the people who want to help you can re-create the problem and test their ideas.
    Also post the results you want from that data, and an explanation of how you get those results from that data, with specific examples.
    Always say which version of Oracle you're using (for example, 11.2.0.2.0).
    See the forum FAQ: https://forums.oracle.com/message/9362002

  • Case with where clause - ORA-00920: Invalid relational operator

    Hi All, when I try to run the query below, I get the following error...
    ORA-00920: invalid relational operator
    00920. 00000 -  "invalid relational operator"
    *Cause:   
    *Action:
    Error at Line: 16 Column: 5
    Does anyone know what's wrong with my query? thanks in advance.
    SELECT concat (year,period)
    FROM DD_ACTUALS_FACT
    WHERE CASE Period
    WHEN 'JAN' THEN '01'
    WHEN 'FEB' THEN '02'
    WHEN 'MAR' THEN '03'
    WHEN 'APR' THEN '04'
    WHEN 'MAY' THEN '05'
    WHEN 'JUN' THEN '06'
    WHEN 'JUL' THEN '07'
    WHEN 'AUG' THEN '08'
    WHEN 'SEP' THEN '09'
    WHEN 'OCT' THEN '10'
    WHEN 'NOV' THEN '11'
    WHEN 'DEC' THEN '12'
    END as "MonthNo"
    ORDER BY CONCAT (year,"MonthNo") DESC

    The problem is the as "MonthNo" - you can't give an "AS" alias to an expression in a where clause.
    You have not actually given any condition, just a set of translations from period into a number.
    You also haven't said what you're trying to do.
    Perhaps you want:
    SELECT concat (year,period)
    FROM DD_ACTUALS_FACT
    WHERE something
    ORDER BY CONCAT (year, CASE Period
    WHEN 'JAN' THEN '01'
    WHEN 'FEB' THEN '02'
    WHEN 'MAR' THEN '03'
    WHEN 'APR' THEN '04'
    WHEN 'MAY' THEN '05'
    WHEN 'JUN' THEN '06'
    WHEN 'JUL' THEN '07'
    WHEN 'AUG' THEN '08'
    WHEN 'SEP' THEN '09'
    WHEN 'OCT' THEN '10'
    WHEN 'NOV' THEN '11'
    WHEN 'DEC' THEN '12'
    END  ) DESC

  • How to change operator of join conditions in where clause?

    Hello
    I have a situation... I want to change the operator between each join conditions in the where clause when these join conditions are not from the same join..
    For example, I have the following schema:
    Dim1 ------ DimA -------Fact1
    Dim1-------DimB -----Fact1
    So DimA and DimB are aliasas of one dim table, but the join is different.
    Now if I run this model, what I will get in the where clause of the query is:
    Where Dim1 = DimA and Dim1 = DimB and DimA= Fact1 and DimB = fact1.
    Is there a way I can change these "and" operator to "OR", so that the where clause would look like this: Where Dim1 = DimA and Dim1 = DimB and DimA= Fact1 OR DimB = fact1?
    This is different from simply changing the join operator within the same join, because these are different joins and I'd like to control how they relate to each other..
    Please help
    Thanks

    Sometimes, business rules are complex, so there isn't always a way to simplify things.  Is your issue that it's complex and error prone, or is it performance due to the OR clauses?
    One possibility that will at least make it easier to test and debug is something like this:  (pseudocode)
    From Table1 Inner join Table2 on x=y etc.etc.
    CROSS APPLY
    (Select case when a=b and (c=d or e=f) then 1 else 0 end) as Situation1
    , case when h=i or j = k then 1 else 0 end) as situation2
    , case when l = m then 1 else 0 end) as situation 3
    ) as CA_Logic_Simplifier
    Where situation1 = 1 and situation2 = 1 and situation3 = 1
    Although you could say, "Hey, this is basically doing the same thing as before", this approach would be far easier to test and debug, because you can at a glance look at the values for situation1, 2, 3, etc. to see where errors are being introduced. 
    The cross apply makes the columns situation1/2/3 "instantiated", so they are usable in the where clause. Divide and conquer.  

  • Using OR operator in the WHERE clause in Oracle BI

    Hi, i am using Oracle BI EE 10.1.3.3.3.
    I construct the simple report in BI Answers on the Accounts presentation layer, and use the following filter clause:
    "WHERE (AccountNum BETWEEN '441' and '473') OR (БалСчет1Порядка BETWEEN '501' and '519')"
    Then i look in the cursor cache and find the real query which is going to database, and it's "where" clause now is:
    "where ( (T45172.BA >= '441' or T45172.BA >= '501') and
    (T45172.BA >= '441' or T45172.BA <= '519') and
    (T45172.BA >= '501' or T45172.BA <= '473') and
    (T45172.BA <= '473' or T45172.BA <= '519') ) "
    Why BI create so many expressions instead of the source 2 expressions?
    How can i force BI to use the source expressions?

    I have the same settings too.
    I post the following query in the Administration web interface, and set the maximum logging level (7):
    SELECT "Plan Account"."Balance Account" saw_0
    FROM "Plan Account"
    WHERE ("Plan Account"."Balance Account" between '441' and '473')
    OR ("Plan Account"."Balance Account" between '501' and '519')
    ORDER BY saw_0
    And got the following BI execution plan:
    RqList <<5619441>> [for database 0:0,0] distinct D1.c1 as c1 [for database 3023:44913,46]
    Child Nodes (RqJoinSpec): <<5619450>> [for database 3023:44913:DB,46]
    RqList <<5619277>> [for database 3023:44913:DB,46]
    D1.c1 as c1 GB [for database 3023:44913,46]
    Child Nodes (RqJoinSpec): <<5619360>> [for database 3023:44913:DB,46]
    RqList <<5619284>> [for database 3023:44913:DB,46]
    Dim - Plan Account.BA as c1 GB [for database 3023:44913,46]
    Child Nodes (RqJoinSpec): <<5619350>> [for database 3023:44913:DB,46]
    TB_PLAN_ACCOUNT T45172
    DetailFilter: (not Dim - Plan Account.BA < '441' or not Dim - Plan Account.BA < '501') and (not Dim - Plan Account.BA < '441' or not '519' < Dim - Plan Account.BA) and (not Dim - Plan Account.BA < '501' or not '473' < Dim - Plan Account.BA) and (not '473' < Dim - Plan Account.BA or not '519' < Dim - Plan Account.BA) [for database 0:0]
    ) as D1
    ) as D1
    OrderBy: c1 asc [for database 0:0,0]
    and following query sent to database:
    -------------------- Sending query to database named DB (id: <<5619277>>):
    select distinct D1.c1 as c1
    from
    (select distinct T45172.BA as c1
    from
    TB_PLAN_ACCOUNT T45172 /* Dim - Plan Account */
    where ( (T45172.BA >= '441' or T45172.BA >= '501') and (T45172.BA >= '441' or T45172.BA <= '519') and (T45172.BA >= '501' or T45172.BA <= '473') and (T45172.BA <= '473' or T45172.BA <= '519') )
    ) D1
    So, i got the same bad where clause...
    What can you advice?

  • Generating HANA where clause for select options having CP as the operator

    Hi All
    I am trying to generate where clause in HANA sql from the select options range table .
    I tried using the function modules  RSDS_RANGE_TO_WHERE and  RH_DYNAMIC_WHERE_BUILD .
    They are working for most of the cases . But  , when the range table has entries like
    Fieldname   sign opt  low high
    VBELN        I/E    CP  *4*
    Both of them fail to generate the right result .
    Could you suggest any other function modules , which take care of all such cases like include single values , exclude single values , incluse and excluse ranges , patterns etc .
    Thanks and Best Regards
    Varsha

    Hi Karthik,
    this is the api, I have done,
    create or replace
    FUNCTION get_where_clause_for_emp_req (
       emp_id       IN   NUMBER,
       salary            IN   NUMBER,
       job         IN   VARCHAR2,
       dept IN NUMBER
       RETURN VARCHAR2
    IS
       l_where_clause   VARCHAR2 (2000);
    BEGIN
       IF (    (emp_id IS NULL)
           AND (salary IS NULL)
           AND (job IS NULL)
           AND (deptIS NULL)
       THEN
          RETURN NULL;
       ELSE
          l_where_clause := 'WHERE ';
       END IF;
       IF (emp_id IS NOT NULL)
       THEN
          l_where_clause :=
                        l_where_clause || ' emp_id =' || emp_id || '';
       END IF;
       IF ((emp_id IS NOT NULL) AND (salary IS NOT NULL))
       THEN
          l_where_clause :=
                          l_where_clause || ' AND salary= ' || salary;
       ELSIF (salary IS NOT NULL)
       THEN
          l_where_clause := l_where_clause || ' salary= ' || salary;
       END IF;
       IF (((salary IS NOT NULL) AND (dept IS NOT NULL)) OR ((emp_id IS NOT NULL) AND (salary IS NULL) AND (dept IS NOT NULL)))
       THEN
          l_where_clause := l_where_clause || ' AND dept= ' || dept;
       ELSIF (status_i IS NOT NULL)
       THEN
          l_where_clause := l_where_clause || ' dept= ' || dept;
       END IF;
    l_where_clause := l_where_clause || ' ;';
       RETURN l_where_clause;
    END;I have done for three parameters, i need to include two more input parameters for this function, so I see going forward my testing cases will increases,
    so am looking for the best solution
    Thanks
    Edited by: NSK2KSN on Jul 7, 2010 3:11 PM

  • Performance - composite index with 'OR' in 'WHERE' clause

    I have a problem with the performance of the following query:
    select /*+ index_asc(omschact oma_index1) */ knr, projnr, actnr from omschact where ((knr = 100 and actnr > 30) or knr > 100)
    and rownum = 1;
    (rownum used only for test purpose)
    index:
    create index on omschact (knr, projnr);
    Execution plan:
    Id Operation
    0 SELECT STATEMENT
    1 COUNT STOPKEY
    2 TABLE ACCESS BY INDEX ROWID
    3 INDEX FULL SCAN
    If I'm correct, the 'OR' in the 'WHERE' clause is responsible for the INDEX FULL SCAN, what makes the query slow.
    A solution would be then to separate the 'WHERE' clause in 2 separate select's (1 with 'knr = 100 and actnr > 30' and 1 with 'knr > 100' and combine the results with a UNION ALL.
    Since it's necessary to have all rows in ascending order (oma_index1) I still have to use an ORDER BY to make sure the order of the rows is correct. This results again in a (too) low performance.
    Another solution that does the trick is to create an index with the 2 fields (knr, projnr) concatenated and to use the same in the 'WHERE' clause:
    create index oma_index2 on omschact (knr || projnr);
    select /*+ index_asc(omschact oma_index2) */ knr, projnr, actnr from omschact where (knr || projnr) > 10030;
    I just can't believe this work-around is the only solution, so I was hoping that someone here knows of a better way to solve this.

    padders,
    I'll give the real data instead of the example. The index I really use consists of 4 fields. In this table the fields are just numbers, but in other tables I need to use char-fields in indexes, so that's why I concatenate instead of using formula's (allthough I would prefer the latter).
    SQL> desc omschact
    Name Null? Type
    KNR NOT NULL NUMBER(8)
    PROJNR NOT NULL NUMBER(8)
    ACTNR NOT NULL NUMBER(8)
    REGELNR NOT NULL NUMBER(3)
    REGEL CHAR(60)
    first methode:
    SQL> create index oma_key_001(knr,projnr,actnr,regelnr);
    Index created.
    SQL> select /*+ index_asc(omschact oma_key_001) */ * from omschact where
    2 (knr > 100 or
    3 (knr = 100 and projnr > 30) or
    4 (knr = 100 and projnr = 30 and actnr > 100000) or
    5 (knr = 100 and projnr = 30 and actnr = 100000 and regelnr >= 0));
    Execution Plan
    Plan hash value: 1117430516
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 11M| 822M| 192K (1)| 00:38:26 |
    | 1 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 11M| 822M| 192K (1)| 00:38:26 |
    |* 2 | INDEX FULL SCAN | OMA_KEY_001 | 11M| | 34030 (1)| 00:06:49 |
    Predicate Information (identified by operation id):
    2 - filter("KNR">100 OR "KNR"=100 AND "PROJNR">30 OR "KNR"=100 AND "PROJNR"=30
    AND "ACTNR">100000 OR "ACTNR"=100000 AND "KNR"=100 AND "PROJNR"=30 AND
    "REGELNR">=0)
    second method (same index):
    SQL> select * from (
    2 select /*+ index_asc(omschact oma_key_001) */ * from omschact where knr > 100
    3 union all
    4 select /*+ index_asc(omschact oma_key_001) */ * from omschact where knr = 100 and projnr > 30
    5 union all
    6 select /*+ index_asc(omschact oma_key_001) */ * from omschact where knr = 100 and projnr = 30 and actnr > 100000
    7 union all
    8 select /*+ index_asc(omschact oma_key_001) */ * from omschact where knr = 100 and projnr = 30 and actnr = 100000 and regelnr > 0)
    9 order by knr, projnr, actnr, regelnr;
    Execution Plan
    Plan hash value: 292918786
    | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 11M| 1203M| | 477K (1)| 01:35:31 |
    | 1 | SORT ORDER BY | | 11M| 1203M| 2745M| 477K (1)| 01:35:31 |
    | 2 | VIEW | | 11M| 1203M| | 192K (1)| 00:38:29 |
    | 3 | UNION-ALL | | | | | | |
    | 4 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 11M| 822M| | 192K (1)| 00:38:26 |
    |* 5 | INDEX RANGE SCAN | OMA_KEY_001 | 11M| | | 33966 (1)| 00:06:48 |
    | 6 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 16705 | 1272K| | 294 (1)| 00:00:04 |
    |* 7 | INDEX RANGE SCAN | OMA_KEY_001 | 16705 | | | 54 (0)| 00:00:01 |
    | 8 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 47 | 3666 | | 4 (0)| 00:00:01 |
    |* 9 | INDEX RANGE SCAN | OMA_KEY_001 | 47 | | | 3 (0)| 00:00:01 |
    | 10 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 1 | 78 | | 4 (0)| 00:00:01 |
    |* 11 | INDEX RANGE SCAN | OMA_KEY_001 | 1 | | | 3 (0)| 00:00:01 |
    Predicate Information (identified by operation id):
    5 - access("KNR">100)
    7 - access("KNR"=100 AND "PROJNR">30)
    9 - access("KNR"=100 AND "PROJNR"=30 AND "ACTNR">100000)
    11 - access("KNR"=100 AND "PROJNR"=30 AND "ACTNR"=100000 AND "REGELNR">0)
    third method:
    SQL> create index oma_test(to_char(knr,'00000000')||to_char(projnr,'00000000')||to_char(actnr,'00000000')||to_char(regelnr,'000'));
    Index created.
    SQL> select /*+ index_asc(omschact oma_test) */ * from omschact where
    2 (to_char(knr,'00000000')||to_char(projnr,'00000000')||
    3 to_char(actnr,'00000000')||to_char(regelnr,'000')) >=
    4 (to_char(100,'00000000')||to_char(30,'00000000')||
    5* to_char(100000,'00000000')||to_char(0,'000'))
    Execution Plan
    Plan hash value: 424961364
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 553K| 55M| 1712 (1)| 00:00:21 |
    | 1 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 553K| 55M| 1712 (1)| 00:00:21 |
    |* 2 | INDEX RANGE SCAN | OMA_TEST | 99543 | | 605 (1)| 00:00:08 |
    Predicate Information (identified by operation id):
    2 - access(TO_CHAR("KNR",'00000000')||TO_CHAR("PROJNR",'00000000')||TO_CHAR("
    ACTNR",'00000000')||TO_CHAR("REGELNR",'000')>=TO_CHAR(100,'00000000')||TO_CHAR(3
    0,'00000000')||TO_CHAR(100000,'00000000')||TO_CHAR(0,'000'))

  • Performance with dates in the where clause

    Performance with dates in the where clause
    CREATE TABLE TEST_DATA
    FNUMBER NUMBER,
    FSTRING VARCHAR2(4000 BYTE),
    FDATE DATE
    create index t_indx on test_data(fdata);
    query 1: select count(*) from TEST_DATA where trunc(fdate) = trunc(sysdate);
    query 2: select count(*) from TEST_DATA where fdate between trunc(sysdate) and trunc(SYSDATE) + .99999;
    query 3: select count(*) from TEST_DATA where fdate between to_date('21-APR-10', 'dd-MON-yy') and to_date('21-APR-10 23:59:59', 'DD-MON-YY hh24:mi:ss');
    My questions:
    1) Why isn't the index t_indx used in Execution plan 1?
    2) From the execution plan, I see that query 2 & 3 is better than query 1. I do not see any difference between execution plan 2 & 3. Which one is better?
    3) I read somewhere - "Always check the Access Predicates and Filter Predicates of Explain Plan carefully to determine which columns are contributing to a Range Scan and which columns are merely filtering the returned rows. Be sceptical if the same clause is shown in both."
    Is that true for Execution plan 2 & 3?
    3) Could some one explain what the filter & access predicate mean here?
    Thanks in advance.
    Execution Plan 1:
    SQL> select count(*) from TEST_DATA where trunc(fdate) = trunc(sysdate);
    COUNT(*)
    283
    Execution Plan
    Plan hash value: 1486387033
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1 | 9 | 517 (20)| 00:00:07 |
    | 1 | SORT AGGREGATE | | 1 | 9 | | |
    |* 2 | TABLE ACCESS FULL| TEST_DATA | 341 | 3069 | 517 (20)| 00:00:07 |
    Predicate Information (identified by operation id):
    2 - filter(TRUNC(INTERNAL_FUNCTION("FDATE"))=TRUNC(SYSDATE@!))
    Note
    - dynamic sampling used for this statement
    Statistics
    4 recursive calls
    0 db block gets
    1610 consistent gets
    0 physical reads
    0 redo size
    412 bytes sent via SQL*Net to client
    380 bytes received via SQL*Net from client
    2 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    1 rows processed
    Execution Plan 2:
    SQL> select count(*) from TEST_DATA where fdate between trunc(sysdate) and trunc(SYSDATE) + .99999;
    COUNT(*)
    283
    Execution Plan
    Plan hash value: 1687886199
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1 | 9 | 3 (0)| 00:00:01 |
    | 1 | SORT AGGREGATE | | 1 | 9 | | |
    |* 2 | FILTER | | | | | |
    |* 3 | INDEX RANGE SCAN| T_INDX | 283 | 2547 | 3 (0)| 00:00:01 |
    Predicate Information (identified by operation id):
    2 - filter(TRUNC(SYSDATE@!)<=TRUNC(SYSDATE@!)+.9999884259259259259259
    259259259259259259)
    3 - access("FDATE">=TRUNC(SYSDATE@!) AND
    "FDATE"<=TRUNC(SYSDATE@!)+.999988425925925925925925925925925925925
    9)
    Note
    - dynamic sampling used for this statement
    Statistics
    7 recursive calls
    0 db block gets
    76 consistent gets
    0 physical reads
    0 redo size
    412 bytes sent via SQL*Net to client
    380 bytes received via SQL*Net from client
    2 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    1 rows
    Execution Plan 3:
    SQL> select count(*) from TEST_DATA where fdate between to_date('21-APR-10', 'dd-MON-yy') and to_dat
    e('21-APR-10 23:59:59', 'DD-MON-YY hh24:mi:ss');
    COUNT(*)
    283
    Execution Plan
    Plan hash value: 1687886199
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    | 0 | SELECT STATEMENT | | 1 | 9 | 3 (0)| 00:00:01 |
    | 1 | SORT AGGREGATE | | 1 | 9 | | |
    |* 2 | FILTER | | | | | |
    |* 3 | INDEX RANGE SCAN| T_INDX | 283 | 2547 | 3 (0)| 00:00:01 |
    Predicate Information (identified by operation id):
    2 - filter(TO_DATE('21-APR-10','dd-MON-yy')<=TO_DATE('21-APR-10
    23:59:59','DD-MON-YY hh24:mi:ss'))
    3 - access("FDATE">=TO_DATE('21-APR-10','dd-MON-yy') AND
    "FDATE"<=TO_DATE('21-APR-10 23:59:59','DD-MON-YY hh24:mi:ss'))
    Note
    - dynamic sampling used for this statement
    Statistics
    7 recursive calls
    0 db block gets
    76 consistent gets
    0 physical reads
    0 redo size
    412 bytes sent via SQL*Net to client
    380 bytes received via SQL*Net from client
    2 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    1 rows processed

    Hi,
    user10541890 wrote:
    Performance with dates in the where clause
    CREATE TABLE TEST_DATA
    FNUMBER NUMBER,
    FSTRING VARCHAR2(4000 BYTE),
    FDATE DATE
    create index t_indx on test_data(fdata);Did you mean fdat<b>e</b> (ending in e)?
    Be careful; post the code you're actually running.
    query 1: select count(*) from TEST_DATA where trunc(fdate) = trunc(sysdate);
    query 2: select count(*) from TEST_DATA where fdate between trunc(sysdate) and trunc(SYSDATE) + .99999;
    query 3: select count(*) from TEST_DATA where fdate between to_date('21-APR-10', 'dd-MON-yy') and to_date('21-APR-10 23:59:59', 'DD-MON-YY hh24:mi:ss');
    My questions:
    1) Why isn't the index t_indx used in Execution plan 1?To use an index, the indexed column must stand alone as one of the operands. If you had a function-based index on TRUNC (fdate), then it might be used in Query 1, because the left operand of = is TRUNC (fdate).
    2) From the execution plan, I see that query 2 & 3 is better than query 1. I do not see any difference between execution plan 2 & 3. Which one is better?That depends on what you mean by "better".
    If "better" means faster, you've already shown that one is about as good as the other.
    Queries 2 and 3 are doing different things. Assuming the table stays the same, Query 2 may give different results every day, but the results of Query 3 will never change.
    For clarity, I prefer:
    WHERE     fdate >= TRUNC (SYSDATE)
    AND     fdate <  TRUNC (SYSDATE) + 1(or replace SYSDATE with a TO_DATE expression, depending on the requirements).
    3) I read somewhere - "Always check the Access Predicates and Filter Predicates of Explain Plan carefully to determine which columns are contributing to a Range Scan and which columns are merely filtering the returned rows. Be sceptical if the same clause is shown in both."
    Is that true for Execution plan 2 & 3?
    3) Could some one explain what the filter & access predicate mean here?Sorry, I can't.

  • How do you use 3 Where Clauses in a query

    Hi, i am trying to figure out how to use 3 Where Clauses in a Query where 2 of the Where Clauses uses a Sub query.
    Display the OrderID of all orders that where placed after all orders placed by “Bottom-Dollar Markets”.
    Order the result by OrderID in ascending order.
    First WHERE clause checks for OrderDate and uses a sub query with ALL keyword.
    Second WHERE clause use equals and sub query.
    Third WHERE clause uses equal and company name.
    This is what i have so far but i am pretty confused on how to do this.
    My Code for NorthWind:
    Select OrderID
    From Orders o
    Where o.OrderID IN (Select OrderDate From Orders Where Orders.OrderID > ALL
    (Select CompanyName From Customers Where CompanyName = 'Bottom-Dollar Markets'));
    The book shows how to use the ALL Keyword but not in a Sub query with Multiple Where Clauses.
    Select VenderName, InvoiceNumber, InvoiceTotal
    FROM Invoices JOIN Vendors ON Invoices.VendorID = Vendors.VendorID
    WHERE InvoiceTotal > ALL (Select InvoiceTotal From Invoices Where VendorID = 34)
    ORDER BY VendorName;

    >Where Orders.OrderDate
    > ALL  (Select
    CompanyName
    The comparison operator (>) requires compatible data types.
    DATETIME is not compatible with VARCHAR string for comparison.
    Here is your homework:
    SELECT orderid
    FROM orders o
    WHERE o.orderdate > ALL (SELECT orderdate
    FROM orders
    WHERE shipvia = (SELECT Max(shipvia)
    FROM orders o
    INNER JOIN customers c
    ON c.customerid =
    o.customerid
    WHERE
    c.companyname = 'Bottom-Dollar Markets'));
    11064
    11065
    11066
    11067
    11068
    11069
    11070
    11071
    11072
    11073
    11074
    11075
    11076
    11077
    Kalman Toth Database & OLAP Architect
    SQL Server 2014 Database Design
    New Book / Kindle: Beginner Database Design & SQL Programming Using Microsoft SQL Server 2014

  • Error while using REMAP_TABLE and WHERE clause  together in IMPDP

    I am trying to move some records from a very large table to another small table.
    I am facing trouble while using REMAP_TABLE and WHERE clause together in IMPDP.
    Problem is data filter is not getting applied and all records are getting imported.
    here is how I have simulated this. please advice.
    CREATE TABLE TSHARRHB.TMP1
      A  NUMBER,
      B  NUMBER
    begin
    Insert into TSHARRHB.TMP1
       (A, B)
    Values
       (1, 1);
    Insert into TSHARRHB.TMP1
       (A, B)
    Values
       (2, 2);
    COMMIT;
    end;
    expdp system/password TABLES=tsharrhb.TMP1 DIRECTORY=GRDP_EXP_DIR DUMPFILE=TMP1.dmp REUSE_DUMPFILES=YES LOGFILE=EXP.log PARALLEL=8
    impdp system/password DIRECTORY=GRDP_EXP_DIR DUMPFILE=TMP1.dmp LOGFILE=imp.log PARALLEL=8 QUERY='TSHARRHB.TMP1:"WHERE TMP1.A = 2"'  REMAP_TABLE=TSHARRHB.TMP1:TMP3 CONTENT=DATA_ONLY
    Import: Release 11.2.0.1.0 - Production on Fri Dec 13 05:13:30 2013
    Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
    Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
    With the Partitioning, Automatic Storage Management, OLAP, Data Mining
    and Real Application Testing options
    Master table "SYSTEM"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
    Starting "SYSTEM"."SYS_IMPORT_FULL_01":  system/********@GRD6.RBSG DIRECTORY=GRDP_EXP_DIR DUMPFILE=TMP1.dmp LOGFILE=SSD_93_TABLES_FULL_EXP.log PARALLEL=8 QUERY=TSHARRHB.TMP1:"WHERE TMP1.A = 2" REMAP_TABLE=TSHARRHB.TMP1:TMP3 CONTENT=DATA_ONLY
    Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
    . . imported "TSHARRHB"."TMP3"                           5.421 KB       2 rows
    Job "SYSTEM"."SYS_IMPORT_FULL_01" successfully completed at 05:13:33
    here I am expecting only 1 record to get imported but both the records are getting imported. please advice.

    The strange thing compared to your output is that I get an error when I have table prefix in the query block:
    Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options
    Master table "SYSTEM"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
    Starting "SYSTEM"."SYS_IMPORT_FULL_01":  system/******** DUMPFILE=TMP1.dmp LOGFILE=imp.log PARALLEL=8 QUERY=SYSADM.TMP1:"WHERE TMP1.A = 2" REMAP_TABLE=SYSADM.TMP1:TMP3 CONTENT=DATA_ONLY
    Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
    ORA-31693: Table data object "SYSADM"."TMP3" failed to load/unload and is being skipped due to error:
    ORA-38500: Unsupported operation: Oracle XML DB not present
    Job "SYSTEM"."SYS_IMPORT_FULL_01" completed with 1 error(s) at Fri Dec 13 10:39:11 2013 elapsed 0 00:00:03
    And if I remove it, it works:
    Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
    With the Partitioning, OLAP, Data Mining and Real Application Testing options
    Master table "SYSTEM"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
    Starting "SYSTEM"."SYS_IMPORT_FULL_01":  system/******** DUMPFILE=TMP1.dmp LOGFILE=imp.log PARALLEL=8 QUERY=SYSADM.TMP1:"WHERE A = 2" REMAP_TABLE=SYSADM.TMP1:TMP3 CONTENT=DATA_ONLY
    Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
    . . imported "SYSADM"."TMP3"                             5.406 KB       1 out of 2 rows
    Job "SYSTEM"."SYS_IMPORT_FULL_01" successfully completed at Fri Dec 13 10:36:50 2013 elapsed 0 00:00:01
    Nicolas.
    PS: as you can see, I'm on 11.2.0.4, I do not have 11.2.0.1 that you seem to use.

  • How to change access path for 'where' clause by using HINTS?

    I searched a loooot of posts and haven't found a solution for my case. I don't even know whether it is possible or not. Is it possible to change the sequence of Oracle "Predicate Information"?
    Here is my SQL and Oracle's execution plan.
      SELECT Max(logId) AS logId FROM online_users_t
      WHERE online_users_date >= to_date('2011-09-19 10:00:00') - 3.2 AND online_users_date <= to_date('2011-09-19 10:00:00') AND online_users_result in (1, -1)
      GROUP BY online_users_user
    | Id  | Operation                    | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT             |                    | 24800 |   629K|  1336   (1)| 00:00:17 |
    |   1 |  HASH GROUP BY               |                    | 24800 |   629K|  1336   (1)| 00:00:17 |
    |*  2 |   TABLE ACCESS BY INDEX ROWID| ONLINE_USERS_T     | 38833 |   985K|  1334   (1)| 00:00:17 |
    |*  3 |    INDEX RANGE SCAN          | ONLINE_USERS_T_IDX |   116K|       |   313   (1)| 00:00:04 |
    Predicate Information (identified by operation id):
       2 - filter("ONLINE_USERS_RESULT"=(-1) OR "ONLINE_USERS_RESULT"=1)
       3 - access("ONLINE_USERS_DATE">=TO_DATE(' 2011-09-16 05:12:00', 'syyyy-mm-dd
                  hh24:mi:ss') AND "ONLINE_USERS_DATE"<=TO_DATE(' 2011-09-19 10:00:00', 'syyyy-mm-dd
                  hh24:mi:ss'))I have 2 conditions in my 'where' clause, one is date range and the other is 'online_users_result in (1, -1)'. It seems that Oracle filter the table by using 'online_users_result in (1, -1)' first, then access it through date range.
    What I want to do is firstly filtering the table by using date range followed by other things. How can I do it?
    Any clue or help would be highly appreciated.
    Thanks in advance.

    It seems that Oracle filter the table by using 'online_users_result in (1, -1)' first, then access it through date range. No it's not.
    What I want to do is firstly filtering the table by using date range followed by other things. How can I do it?That's precisely what it's doing now.
    It is using the T_IDX index to quickly find all rows that satisfy the range predicate on the date column.
    And then filter those rows to only retrieve the ones that satisfy the other predicate (... in (1,-1)).

Maybe you are looking for