Subquery and NVL

Hi All,
I am trying to write a query like the following.
Select *
from tablea
where tablea.col1 IN nvl((select value from tableb),tablea.col1)
Now problem comes when there are multiple rows returned by subquery at that time Nvl will fail ,also if subquery is not returning any row i want to show all rows of tablea,so somehow i want to get functionality of nvl for multiple rows.
Please help me out ,i have thought of outer join but then is it going to work??
Regards,
Sandeep

Hi,
Select *
from tablea
where tablea.col1 IN nvl((select value from tableb),tablea.col1)
you go for left outer join
Select *
from tablea,tableb
where tablea.col1(+) = tableb.value;
Cheers
Pavan Kumar N

Similar Messages

  • Whats the difference between nullif and nvl

    hi,
    i have a doubt in using nullif and nvl.can anybody tell me the difference.
    because in some places we cant use nullif in the place of nvl.if iam right nvl is used mainly for datatype as numeric.???am i right...
    if iam wrong correct me.
    pls help me out..
    thanks,
    Ratheesh

    They are quite opposite functions.
    nullif(a,b) means 'case when a = b then NULL else a end'
    nvl(a,b) means 'case when a is null then b else a end'
    nvl2(a,b,c) means 'case when a is null then b else c end'.
    Please refer [url http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14200/functions001.htm#i88893]SQL Functions, NULL-Related Functions.

  • Problem creating a table with a subquery and a dblink

    Hello!!
    I have a little problem. When I create a table with a subquery and a dblink, for example:
    CREATE TABLE EXAMPLE2 AS SELECT * FROM EXAMPLE1@DBLINK
    the table definition is changed. Fields with a type of CHAR or VARCHAR2 are created with a size three times bigger than the original table in the remote database. Field of type DATE and NUMBER are not changed. For example if the original table, in the database 1, has a field of type CHAR(1) it is create in the local database with a type of CHAR(3), and a VARCHAR2(5) field is created with VARCHAR2(15).
    Database 1 has a WE8DEC character set.
    Database 2 has a AL32UTF8 character set.
    Could it be related to the difference in character sets?
    What can I do to make Oracle use the same table definition when creating a table in this way?
    Thanks!!

    That is related to character sets, and probably necessary if you want all the data in the remote table to be able to fit in the new table.
    When you declare a column VARCHAR2(5), by default, you're allocating 5 bytes of storage. In a single-byte character set, which I believe WE8DEC is, that also happens to equate to 5 characters. In a multi-byte character set like AL32UTF8, though, 1 character may require up to 3 bytes of storage, so you'd need to allocate 15 bytes to store that data. That's what's going on here.
    You could still store all the data if you create the table locally by explicitly requesting 5 characters of storage by declaring the column VARCHAR2(5 CHAR). You could also set the NLS_LENGTH_SEMANTICS parameter to CHAR rather than BYTE before creating the table, but I believe that both of these will only apply when you're explicitly defining columns as part of your CREATE TABLE. I don't believe either will apply to CTAS statements.
    Justin

  • Difference between a regular subquery and a correlated subquery

    Can someone explain EXACTLY what is a correlated subquery and could you give me an example? I'm taking an Oracle DBA class and I would appreciate your feedback. Thanks. :)

    "Normal" subquery (the subquery is executed only once for the statement):
    select name
    from emp
    where salary > (select avg(emp2.salary) from emp emp2);
    Correlated subquery (it is executed for each row of the main query):
    select name
    from emp
    where salary > (select avg(salary) from emp emp2
    where emp2.deptno = emp.deptno);
    Can someone explain EXACTLY what is a correlated subquery and could you give me an example? I'm taking an Oracle DBA class and I would appreciate your feedback. Thanks. :)

  • Min and NVL with subquery

    Hello,
    Below is my query
                     select  nvl( min(csp.coeficient_value),  (select csp1.coeficient_value
                                                                 from csp csp1
                                                                where csp1.rule_code = 'A55' )) coeffient_value
                       from adr,
                            sec,
                            rpr,
                            csp
                      where adr.adr_id = sec.adr_id
                        and sec.account_id = 663799
                        and adr.pcode between rpr.start_pcode and rpr.end_pcode
                        and rpr.rule_code = csp.rule_code
                        and sysdate between csp.start_date and csp.end_date when i run this query it is giving me an error "ORA-00933: SQL command not properly ended"
    Can anyone help me with this?
    As i don't want to hardcode the value of rule 'A55' and want to retrieve from database.
    Thanks for your help.
    Message was edited by:
    AB

    By using below query my problem is resolved.
    select nvl(coeffient_value, (select csp1.coeficient_value
                                                                 from csp csp1
                                                                where csp1.rule_code = 'A55' ))
    from (
    select  min(csp.coeficient_value)  coeffient_value
                       from adr,
                            sec,
                            rpr,
                            csp
                      where adr.adr_id = sec.adr_id
                        and sec.account_id = 663799
                        and adr.pcode between rpr.start_pcode and rpr.end_pcode
                        and rpr.rule_code = csp.rule_code
                        and sysdate between csp.start_date and csp.end_date )Thanks to all for helping me.

  • Bad execution plans when using parameters, subquery and partition by

    We have an issue with the following...
    We have this table:
    CREATE TABLE dbo.Test (
    Dt date NOT NULL,
    Nm int NOT NULL,
    CONSTRAINT PK_Test PRIMARY KEY CLUSTERED (Dt)
    This table can have data but it will not matter for this topic.
    Consider this query (thanks Tom Phillips for simplifying my question):
    declare @date as date = '2013-01-01'
    select *
    from (
    select Dt,
    row_number() over (partition by Dt order by Nm desc) a
    from Test
    where Dt = @date
    ) x
    go
    This query generates an execution plan with a clustered seek.
    Our queries however needs the parameter outside of the sub-query:
    declare @date as date = '2013-01-01'
    select *
    from (
    select Dt,
    row_number() over (partition by Dt order by Nm desc) a
    from Test
    ) x
    where Dt = @date
    go
    The query plan now does a scan followed by a filter on the date.
    This is extremely inefficient.
    This query plan is the same if you change the subquery into a CTE or a view (which is what we use).
    We have this kind of setup all over the place and the only way to generate a good plan is if we use dynamic sql to select data from our views.
    Is there any kind of solution for this?
    We have tested this (with the same result) on SQL 2008R2, 2012 SP1, 2014 CU1.
    Any help is appreciated.

    Hi Tom,
    Parameter sniffing is a different problem. A query plan is made based on the value which may be really off in the data distribution. We do have this problem as well e.g. when searching for today's data when the statistics think the table only has yesterday's
    data (a problem we have a lot involves the lack of sufficient amount of buckets in statistics objects).
    This problem is different.
    - It doesn't matter what the parameter value is.
    - You can reproduce this example with a fresh table. I.e. without statistics.
    - No matter what the distribution of data (or even if the statistics are correct), there is absolutely no case possible (in my example) where doing a scan followed by a filter should have better results than doing a seek.
    - You can't change the behavior with hints like "option(recompile)" or "optimize for".
    This problem has to do with the specific combination of "partition by" and the filter being done outside of the immediate query. Try it out, play with the code, e.g. move the where clause inside the subquery. You'll see what I mean.
    Thanks for responding.
    Michel

  • SELECT * and NVL

    I would like to use a SELECT * FROM myTable and if the value stored in Oracle is "null", then I would like to replace "null" with a blank space using the NVL function. Can anyone describe how to do this? I though maybe it would just be SELECT nvl(*, ' ') FROM myTable but this is not working properly.
    Thanks for the help...
    Zac

    The NVL function like virtually all Oracle functions except COUNT requires a "real" value, like a column name or an expression that resolves to a value.
    The only way is to code
    SELECT col1,col2,NVL(col3,' ')
    FROM my_table

  • Sum and nvl in a query

    Greedings,
    how is it possible in reports to give a nvl in a query that im getting a summation? For example in my follow query im trying to return d.bas_amount in case VARIANCE is null. Thanks for any help in advance
    Sum(((select d.bas_amount from so_budgets d1 where d1.acnt_code = d.acnt_code
    and Trim(d.period) BETWEEN :P_FROM AND :P_TO AND ROWNUM=1)-
    (SELECT kl.amount FROM & a01_a_salfldg @oracle_to_sun kl WHERE Trim(kl.accnt_code)=Trim(a.acnt_code) AND kl.period between :P_FROM AND :P_TO AND ROWNUM=1))) AS VARIANCE
    ----------------------

    i'm not sure if this works ... but try to add a NVL():
    NVL(SUM((  (SELECT d.bas_amount
                       FROM   so_budgets d1
                       WHERE  d1.acnt_code = d.acnt_code
                       AND    TRIM(d.period) BETWEEN :p_from AND :p_to
                       AND    ROWNUM = 1)
                    - (SELECT kl.amount
                       FROM   a01_a_salfldg kl
                       WHERE  TRIM(kl.accnt_code) = TRIM(a.acnt_code)
                       AND    kl.period BETWEEN :p_from AND :p_to
                       AND    ROWNUM = 1)
               (SELECT d.bas_amount
                FROM   so_budgets d1
                WHERE  d1.acnt_code = d.acnt_code
                AND    TRIM(d.period) BETWEEN :p_from AND :p_to
                AND    ROWNUM = 1)) AS VARIANCE

  • Trouble with subquery and rownum and ordering

    I'm having trouble making this subquery work. The basic idea is that the web app will show only so many rows of results on the page, but right now I'm just playing around in SQL*Plus. The address book holds mixed case, so in order to sort by name properly I need to use UPPER to ignore case sensitivity. This SQL statement works fine for me:
    select addressbookid from addressbook where addressbookid like '905430931|%' order by upper(addressbookid);I know that if you mention ROWNUM in the WHERE clause, you're referring to the row numbers of the ResultSet that Oracle returns. How do I use both ORDER BY UPPER(ADDRESSBOOKID) and WHERE ROWNUM > 25 AND ROWNUM <= 50? I figured a subquery would do it, but I can't write a correct one that does it! Below are my 2 attempts with the errors, and then I just tried to play with rownum:
    SQL> select addressbookid from addressbook where addressbookid in (select addressbookid from address book where addressbookid like '905430931|%' order by upper(addressbookid));
    select addressbookid from addressbook where addressbookid in (select addressbookid from addressbook
    ERROR at line 1:
    ORA-00907: missing right parenthesis
    SQL> select addressbookid from addressbook where addressbookid in upper(select addressbookid from addressbook where addressbookid like '905430931|%');
    select addressbookid from addressbook where addressbookid in upper(select addressbookid from address
    ERROR at line 1:
    ORA-00936: missing expression
    SQL> select addressbookid from addressbook where addressbookid like '905430931|%' and rownum > 25 and rownum <= 50 order by upper(addressbookid);
    no rows selected
    SQL> select addressbookid from addressbook where addressbookid like '905430931|%' and rownum > 25 and rownum <= 50;
    no rows selectedLike I said, if I can get a working subquery, then I'd like to attach that restriction on the rownum stuff. I'm wondering if it will be a problem trying to get the ordering to happen and then the rownum restriction after that, and all in the same query...
    Btw, we've made all the table and column names in our database uppercase, so that shouldn't matter.

    This is probably the most efficient way ...
    select addressbookid
    from
       select addressbookid,
       rownum rn
       from
          select addressbookid
          from addressbook
          where addressbookid like '905430931|%'
          order by addressbookid
       where rownum <= 50
    where rn > 25

  • Using disticnt and nvl together

    Hi,
    Is it possible to use nvl with distinct?
    When no data is returned, the value should should be 0.
    How do I get use nvl in the code to get a value 0 when no data is returned?
    I tried using distinct(nvl(lbt.bsl_det_koers,0)), but tis still show 'no data found'.
    select  distinct(LBT.BSL_DET_KOERS)
    FROM    lgl_beslagleggingen_det lbt
    ,       lgl_referentie lre
    where   LBT.BSL_DET_VALUTA = LRE.REF_ID
    and     LBT.BSL_ID = 6
    and     LRE.REF_AFKORTING = 'USD';Thanks,
    Diana

    You can do like this,
    WITH T
         AS (SELECT DISTINCT (LBT.BSL_DET_KOERS)
               FROM lgl_beslagleggingen_det lbt, lgl_referentie lre
              WHERE LBT.BSL_DET_VALUTA = LRE.REF_ID
                AND LBT.BSL_ID = 6
                AND LRE.REF_AFKORTING = 'USD')
    SELECT * FROM T
    UNION ALL
    SELECT 0
      FROM DUAL
    WHERE NOT EXISTS (SELECT 1 FROM t)G.

  • Subquery  and case when

    hi
    i have the following script
    if run the subquery individually it rgives me result
    but when try to run the whiole query i get error
    at line as from kyword not found where expected
    the query is
    SELECT
    Q2.BRANCH,
    Q2.NAMETITLE,
    Q2.PRD,
    Q2.LONGNAME,
    Q2.BALANCE1,
    Q2.BALANCE2,
    Q2.BALANCE3,
    Q2.BALANCE4,
    Q2.BALANCE5,
    Q1.REMARK
    FROM
    SELECT
    PRDACCTID PRD,
    LBRCODE BRANCH,
    case
    when
         (prdacctid,lbrcode) in 
              select prdacctid,lbrcode from d010053
                     where (lbrcode,prdacctid)
              in (
                   select lbrcode,prdacctid from d009022 where acctstat<>3
                   and (lbrcode,trim(substr(prdacctid,1,8))) in
                        (select lbrcode,trim(prdcd) from d009021 where moduletype in (10,11,12))
         and nametype=1
    then
         'yes'
    else
         'no'
    end
    ) as remark
    FROM D009022
    WHERE ACTSTAT<>3
    AND TRIM(SUBSTR(PRDACCTID,1,8)) IN ('SB','CD','CC')
       )Q1,
              SELECT
              BRANCH,
              NAMETITLE,
              PRD,
              LONGNAME,
              BALANCE1,
              BALANCE2,
              BALANCE3,
              BALANCE4,
              BALANCE5,
              FROM
                        SELECT A.*,B.* ,
                        A.PRDACCTID PRD,
                        A.LBRCODE BRANCH,
                        RANK() OVER(PARTITION BY B.LBRCODE,B.PRDACCTID ORDER BY B.CBLDATE DESC) AS RNK
                        FROM D009022 A,D010014 B
                        WHERE A.LBRCODE=B.LBRCODE
                        AND A.PRDACCTID=B.PRDACCTID
                        AND CBLDATE<'01-APR-09'
                        AND A.ACCTSTAT!=3
                        AND (TRIM(SUBSTR(A.PRDACCTID,1,8)),A.LBRCODE) IN
                        (SELECT TRIM(PRDCD),LBRCODE FROM D009021 WHERE MODULETYPE IN (10,11,12,13,14,30))
                   WHERE RNK=1
       )Q2
    WHERE Q1.BRANCH=Q2.BRANCH
    AND Q1.PRD=Q2.PRD
    /

    If you formatted your query better, then you might have spotted the issue yourself...
    In your Q2 query, you've got "BALANCE5 *,* FROM ..." so remove the extra comma, like so:
    SELECT Q2.BRANCH,
           Q2.NAMETITLE,
           Q2.PRD,
           Q2.LONGNAME,
           Q2.BALANCE1,
           Q2.BALANCE2,
           Q2.BALANCE3,
           Q2.BALANCE4,
           Q2.BALANCE5,
           Q1.REMARK
    FROM  (SELECT PRDACCTID PRD,
                  LBRCODE BRANCH,
                  case when (prdacctid,lbrcode) in (select prdacctid,lbrcode
                                                    from   d010053
                                                    where  (lbrcode,prdacctid) in (select lbrcode,prdacctid
                                                                                   from   d009022
                                                                                   where  acctstat != 3
                                                                                   and    (lbrcode,trim(substr(prdacctid,1,8))) in (select lbrcode,trim(prdcd)
                                                                                                                                    from   d009021
                                                                                                                                    where  moduletype in (10,11,12)))
                                                    and    nametype=1)
                             then 'yes'
                       else 'no'
                  end as remark
           FROM   D009022
           WHERE  ACTSTAT != 3
           AND    TRIM(SUBSTR(PRDACCTID,1,8)) IN ('SB','CD','CC')) Q1,
          (SELECT BRANCH,
                  NAMETITLE,
                  PRD,
                  LONGNAME,
                  BALANCE1,
                  BALANCE2,
                  BALANCE3,
                  BALANCE4,
                  BALANCE5    -- removed extra comma from here
           FROM   (SELECT A.*,B.* ,
                          A.PRDACCTID PRD,
                          A.LBRCODE BRANCH,
                          RANK() OVER(PARTITION BY B.LBRCODE,B.PRDACCTID ORDER BY B.CBLDATE DESC) AS RNK
                   FROM   D009022 A,D010014 B
                   WHERE  A.LBRCODE=B.LBRCODE
                   AND    A.PRDACCTID=B.PRDACCTID
                   AND    CBLDATE < to_date('01/04/2009', 'dd/mm/yyyy')
                   AND    A.ACCTSTAT != 3
                   AND    (TRIM(SUBSTR(A.PRDACCTID,1,8)),A.LBRCODE) IN (SELECT TRIM(PRDCD),LBRCODE
                                                                        FROM   D009021
                                                                        WHERE  MODULETYPE IN (10,11,12,13,14,30)))
           WHERE  RNK=1) Q2
    WHERE  Q1.BRANCH = Q2.BRANCH
    AND    Q1.PRD = Q2.PRDEdited by: Boneist on 06-Aug-2009 10:20
    Added in the to_date around the date which I forgot to point out earlier (but BluShadow has already done so!)
    Also added in a comment on the line I removed the extra comma from.

  • Subquery inside NVL using a view

    Hello
    A subquery can not be used inside a NVL.
    But I read that it can be done using a view.
    Can any one give an example of how we can acheive the effect of NVL (select statement, <expr>) using a view.
    (Just in general ....)
    Thank you

    Who said that
    SQL>SELECT empno
      2        ,ename
      3        ,comm
      4       ,NVL(to_char(comm), (SELECT 'Commision is NULL' FROM DUAL))  null_comm
      5    FROM emp ;
         EMPNO ENAME            COMM NULL_COMM
          7369 SMITH                 Commision is NULL
          7499 ALLEN             300 300
          7521 WARD              500 500
          7566 JONES                 Commision is NULL
          7654 MARTIN           1400 1400
          7698 BLAKE                 Commision is NULL
          7782 CLARK                 Commision is NULL
          7788 SCOTT                 Commision is NULL
          7839 KING                  Commision is NULL
          7844 TURNER              0 0
          7876 ADAMS                 Commision is NULL
          7900 JAMES                 Commision is NULL
          7902 FORD                  Commision is NULL
          7934 MILLER                Commision is NULL
    14 rows selected.
    SQL>Regards
    Arun

  • Subquery and procedure  - problem

    Hello,
    I have procedure created with option "WITH RESULT VIEW ProcViewTest1".
    When I try to execute statement below everything is ok.
    select * from ProcViewTest1 WITH PARAMETERS ('placeholder' = ('$$str1$$', 'Michal'))
    But when I try to execute:
    select *, (select * from ProcViewTest1 WITH PARAMETERS ('placeholder' = ('$$str1$$', 'Michal'))) as col1 from dummy
    I have error: "sql syntax error: incorrect syntax near "WITH"
    I checked that in the case of procedures without parameters can be used as a subquery.
    Why I have this message?
    What shoul I do?
    Maybe the error is in syntax?
    Best regards,

    Hello,
    I have procedure created with option "WITH RESULT VIEW ProcViewTest1".
    When I try to execute statement below everything is ok.
    select * from ProcViewTest1 WITH PARAMETERS ('placeholder' = ('$$str1$$', 'Michal'))
    But when I try to execute:
    select *, (select * from ProcViewTest1 WITH PARAMETERS ('placeholder' = ('$$str1$$', 'Michal'))) as col1 from dummy
    I have error: "sql syntax error: incorrect syntax near "WITH"
    I checked that in the case of procedures without parameters can be used as a subquery.
    Why I have this message?
    What shoul I do?
    Maybe the error is in syntax?
    Best regards,

  • Solution for this but in single query without using  subquery and all

    My Table Structure be like this
    empid sal
    100 5000
    200 3000
    300 2000
    400 1000
    I want the ouput like this
    empid sal Running Total
    100 5000 5000
    200 3000 8000
    300 2000 10000
    400 1000 11000

    You mean something like
    select empno, sal, sum(sal) over (order by empno) from emp order by empno
    EMPNO,SAL,SUM(SAL)OVER(ORDERBYEMPNO)
    4444,,
    7369,100,100
    7499,200,300
    7521,100,400
    7566,100,500
    7654,1250,1750
    7698,2850,4600
    7782,2450,7050
    7788,100,7150
    7839,5000,12150
    7844,1500,13650
    7876,1100,14750
    7900,950,15700
    7902,3000,18700
    7934,1300,20000

  • Subquery, TO_NUMBER and ORA-01722 invalid number

    I'm running into a invalid number error (ORA-01722) when I expect none.
    I have a table that stores a semester term as a VARCHAR2, all term codes are actually numbers like 200609. There is one exception which I filter out, using a subquery, to prevent the invalid number error.
    My query looks like this:
    SELECT NVL(SUM(s.balance))
    FROM (SELECT s1.term, s1.balance
    FROM student_account s1
    WHERE s1.student_id = :student_id
    AND s1.term <> 'SCRIPT') s
    WHERE TO_NUMBER(s.term) <= 200609;
    The query errors with ORA-01722.
    Now I've checked and rechecked that there isn't another bad term that is not a number.
    SELECT DISTINCT '[' || term || ']'
    FROM student_account
    WHERE student_id = :student_id;
    The error complains at line of the WHERE clause.
    I've ran just the subquery and changed the column list to select distinct term. All terms are numbers. I think that the outer WHERE clause for some reason still gets the 'SCRIPT' term. Though I've tried to verify this with no luck.
    I created a function that simply takes the term writes it to DBMS_OUTPUT and returns it as a VARCHAR2. The weird thing is then the query works. For example the outer WHERE clause becomes: WHERE TO_NUMBER(PRINT_TERM(s.term)) <= 200609
    I've also tried to move the TO_NUMBER to the subquery without any luck, same error.
    Anyone know what is going on?

    Oracle is allowed to push predicates into the subquery, so there is no guarantee that the problem row is filtered out before TO_NUMBER is called. You can get into some very interesting discussions about whether this is the right behavior from a relational theory and/or ANSI standard perspective, but you're probably stuck with the behavior (unless you want to get Oracle to rework their optimizer)
    One way to get around the problem would be to write a my_to_number function that catches the error and returns NULL if the to_number conversion fails, i.e.
    CREATE FUNCTION my_to_number( p_num IN VARCHAR2 )
      RETURN NUMBER
    IS
      l_num number;
    BEGIN
      l_num := to_number( p_num );
      RETURN l_num;
    EXCEPTION
      WHEN <<Exception whose name escapes me>> THEN
        RETURN NULL;
    END;And use that in your query.
    Justin
    Message was edited by:
    Justin Cave

Maybe you are looking for