Home » SQL & PL/SQL » SQL & PL/SQL » Case statement (SQL Developer)
Case statement [message #597580] Mon, 07 October 2013 00:56 Go to next message
davron0
Messages: 12
Registered: October 2013
Junior Member
hi,

new to forum and Developer in general, an accountant so bare with me on my programming skills, or lack there of, in the below query i want to pull information from not only figures >10 but also <-10, i had to put a case statement in because before it was returning no data, as it believed i was dividing by zero...long story short, how can i adapt this to pull in for both sets of data...

advise greatly welcomed

SELECT ALL AMS.EGALISATION.NPTF AS Fund,
AMS.EGALISATION.TPARTS AS Shareclass,
EGALISATION_A1.DATE_NAV AS "Current Day",
EGALISATION_A1.RNI_PART AS "Current Income",
AMS.EGALISATION.DATE_NAV AS "Previous Day",
AMS.EGALISATION.RNI_PART AS "Previous Income",
CASE
WHEN AMS.EGALISATION.RNI_PART = 0
THEN 0
ELSE (EGALISATION_A1.RNI_PART - AMS.EGALISATION.RNI_PART) / AMS.EGALISATION.RNI_PART * 100
END AS "% Movement"
FROM AMS.EGALISATION,
AMS.EGALISATION EGALISATION_A1
WHERE (AMS.EGALISATION.NPTF = EGALISATION_A1.NPTF)
AND (AMS.EGALISATION.TPARTS = EGALISATION_A1.TPARTS)
AND (AMS.EGALISATION.CEGA = EGALISATION_A1.CEGA)
AND
CASE
WHEN AMS.EGALISATION.RNI_PART = 0
THEN 0
ELSE (EGALISATION_A1.RNI_PART - AMS.EGALISATION.RNI_PART) / AMS.EGALISATION.RNI_PART * 100
END > 10
AND ((AMS.EGALISATION.NPTF LIKE 'S2%'
OR (AMS.EGALISATION.NPTF LIKE 'S1%'
AND (AMS.EGALISATION.NPTF NOT LIKE 'S25%')))
AND (AMS.EGALISATION.DATE_NAV = TRUNC(SysDate) - 4
AND EGALISATION_A1.DATE_NAV = TRUNC(SysDate) - 1)
AND AMS.EGALISATION.CEGA = 'GB')
ORDER BY AMS.EGALISATION.NPTF

[Updated on: Mon, 07 October 2013 08:12] by Moderator

Report message to a moderator

Re: Case statement [message #597582 is a reply to message #597580] Mon, 07 October 2013 01:03 Go to previous messageGo to next message
Littlefoot
Messages: 21808
Registered: June 2005
Location: Croatia, Europe
Senior Member
Account Moderator
Did you try OR (instead of CASE)? Such as
SQL> with test as
  2    (select -20 id, 'A' val from dual union
  3     select  -5, 'B' from dual union
  4     select   7, 'C' from dual union
  5     select  16, 'D' from dual
  6    )
  7  select id, val
  8  from test
  9  where (   id < -10
 10         or id >  10
 11        );

        ID V
---------- -
       -20 A
        16 D

SQL>
Re: Case statement [message #597584 is a reply to message #597582] Mon, 07 October 2013 01:07 Go to previous messageGo to next message
davron0
Messages: 12
Registered: October 2013
Junior Member
yes, which seems like the most obvious and simple solution but the Query doesnt like that
Re: Case statement [message #597586 is a reply to message #597584] Mon, 07 October 2013 01:18 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
So what is the issue now? Is the query returning you expected records? Post the DDLs and few insert statements.
Re: Case statement [message #597587 is a reply to message #597586] Mon, 07 October 2013 01:23 Go to previous messageGo to next message
davron0
Messages: 12
Registered: October 2013
Junior Member
the issue is as i said above, my query only returns those that are over >10, i need to find a way to write it so it also returns those that are <-10, the OR statement wont work, or certainly not the way i am writing

pardon my ignorance but what you mean DDLs?
Re: Case statement [message #597589 is a reply to message #597587] Mon, 07 October 2013 01:30 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
davron0 wrote on Mon, 07 October 2013 11:53
my query only returns those that are over >10, i need to find a way to write it so it also returns those that are <-10, the OR statement wont work, or certainly not the way i am writing


Did you try LF's code? The OR should work properly. Can you run the code in SQL*Plus and paste it here.

Quote:
what you mean DDLs?


DDL - Data Definition Language, simply means, please post the create table scripts and few insert statements.
Re: Case statement [message #597590 is a reply to message #597589] Mon, 07 October 2013 01:38 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
Another thing, you need to use CASE whenever you have a situation of IF-THEN-ELSE. In your case, the THEN part is same in either conditions, i.e. id>10 OR id<-10, so CASE is not required.
Re: Case statement [message #597591 is a reply to message #597589] Mon, 07 October 2013 01:39 Go to previous messageGo to next message
davron0
Messages: 12
Registered: October 2013
Junior Member
Yes i need the case statement, as previously i got the error message "Divisor is zero", after Googling the recommendation was to use a CASE statement.

unfortunately i dont know what any of the bottom of your reply means, or how to go about it, this could be a slow process i fear...
icon5.gif  Re: Case statement [message #597594 is a reply to message #597587] Mon, 07 October 2013 01:43 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Quote:
the OR statement wont work,


Why?

Re: Case statement [message #597595 is a reply to message #597594] Mon, 07 October 2013 01:49 Go to previous messageGo to next message
davron0
Messages: 12
Registered: October 2013
Junior Member
i guess i may be using the OR statement incorrectly
Re: Case statement [message #597597 is a reply to message #597595] Mon, 07 October 2013 01:55 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
davron0 wrote on Mon, 07 October 2013 12:19
i guess i may be using the OR statement incorrectly


It's not about the OR, it was just a hint for you to avoid CASE. But you need a workaround to get rid off the "ORA-01476: divisor is equal to zero" error.

If I understand correctly, this is the issue you are facing -

SQL> WITH TEST AS
  2   (SELECT -20 ID, 10 VAL
  3      FROM DUAL
  4    UNION
  5    SELECT -15, 0
  6      FROM DUAL
  7    UNION
  8    SELECT 70, 2
  9      FROM DUAL
 10    UNION
 11    SELECT 160, -10 FROM DUAL)
 12  SELECT ID / VAL my_out
 13    FROM TEST
 14   WHERE (ID < -10 OR ID > 10);

ORA-01476: divisor is equal to zero


You need to use proper DECODE and NVL to fix it.

SQL> WITH TEST AS
  2   (SELECT -20 ID, 10 VAL
  3      FROM DUAL
  4    UNION
  5    SELECT -15, 0
  6      FROM DUAL
  7    UNION
  8    SELECT 70, 2
  9      FROM DUAL
 10    UNION
 11    SELECT 160, -10 FROM DUAL)
 12  SELECT NVL (ID / DECODE(VAL, 0, NULL, VAL), 0) my_out
 13    FROM TEST
 14   WHERE (ID < -10 OR ID > 10);
 
    MY_OUT
----------
        -2
         0
        35
       -16



Regards,
Lalit
Re: Case statement [message #597605 is a reply to message #597580] Mon, 07 October 2013 03:10 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
davron0 wrote on Mon, 07 October 2013 11:26

CASE
    WHEN AMS.EGALISATION.RNI_PART = 0
    THEN 0
    ELSE (EGALISATION_A1.RNI_PART - AMS.EGALISATION.RNI_PART) / AMS.EGALISATION.RNI_PART * 100
  END AS "% Movement"



So, apropos my demonstration in above post, your code woould become -

NVL((EGALISATION_A1.RNI_PART - AMS.EGALISATION.RNI_PART) / DECODE(AMS.EGALISATION.RNI_PART,0, NULL, AMS.EGALISATION.RNI_PART) * 100,0)


Regards,
Lalit
Re: Case statement [message #597607 is a reply to message #597605] Mon, 07 October 2013 03:18 Go to previous messageGo to next message
pablolee
Messages: 2882
Registered: May 2007
Location: Scotland
Senior Member
Not seeing the point of that at all Lalit. All you have done is replace one conditional structure with another.
In addition, you where clause in your demo would not meet requirements as the restriction should be on the calculation not he column
i.e.
egl.rni_part >10 or egl.rni_part <-10 is pointless since the boundary check should be on
CASE WHEN egl.rni_part = 0
THEN 0
ELSE (eg2.rni_part - egl.rni_part) / egl.rni_part * 100
END > 10
(Whichever way you choose to write the calculation.)

@OP, our confusion here lies with the fact that this really should work the way that Littlefoot has said, therefore we are going to need more info. Could you post what you tried using the OR in the first instance.



Re: Case statement [message #597609 is a reply to message #597595] Mon, 07 October 2013 03:34 Go to previous messageGo to next message
davron0
Messages: 12
Registered: October 2013
Junior Member
I re-wrote as per Lalit advise(i think) but still not working
SELECT ALL AMS.EGALISATION.NPTF AS Fund,
AMS.EGALISATION.TPARTS AS Shareclass,
EGALISATION_A1.DATE_NAV AS "Current Day",
EGALISATION_A1.RNI_PART AS "Current Income",
AMS.EGALISATION.DATE_NAV AS "Previous Day",
AMS.EGALISATION.RNI_PART AS "Previous Income",
NVL((EGALISATION_A1.RNI_PART - AMS.EGALISATION.RNI_PART) / DECODE(AMS.EGALISATION.RNI_PART, 0, NULL, AMS.EGALISATION.RNI_PART) * 100, 0) AS OUTPUT
FROM AMS.EGALISATION,
AMS.EGALISATION EGALISATION_A1
WHERE (AMS.EGALISATION.NPTF = EGALISATION_A1.NPTF)
AND (AMS.EGALISATION.TPARTS = EGALISATION_A1.TPARTS)
AND (AMS.EGALISATION.CEGA = EGALISATION_A1.CEGA)
AND ((AMS.EGALISATION.NPTF LIKE 'S2%'
OR (AMS.EGALISATION.NPTF LIKE 'S1%'
AND (AMS.EGALISATION.NPTF NOT LIKE 'S25%')))
AND (AMS.EGALISATION.DATE_NAV = TRUNC(SysDate) - 4
AND EGALISATION_A1.DATE_NAV = TRUNC(SysDate) - 1)
AND NVL((EGALISATION_A1.RNI_PART - AMS.EGALISATION.RNI_PART) / DECODE(AMS.EGALISATION.RNI_PART, 0, NULL, AMS.EGALISATION.RNI_PART) * 100, 0) > 10 OR <-10)
AND AMS.EGALISATION.CEGA = 'GB')
ORDER BY AMS.EGALISATION.NPTF
Re: Case statement [message #597610 is a reply to message #597607] Mon, 07 October 2013 03:37 Go to previous messageGo to next message
davron0
Messages: 12
Registered: October 2013
Junior Member
pablolee wrote on Mon, 07 October 2013 16:18

@OP, our confusion here lies with the fact that this really should work the way that Littlefoot has said, therefore we are going to need more info. Could you post what you tried using the OR in the first instance.





I literally just replaced the CASE with OR as i was not sure how to write it, but will the OR fix my issue related to the Divisor being equal to Zero? thats where the original issues occured
Re: Case statement [message #597611 is a reply to message #597609] Mon, 07 October 2013 03:39 Go to previous messageGo to next message
pablolee
Messages: 2882
Registered: May 2007
Location: Scotland
Senior Member
Hi Davron, it's really quite difficult to read what you have posted. In future, can you put your code between code tags:
[code]your code goes in here[/code]

But I can see the issue:
you can't write conditions like this:

where col_value >10 or <-10

Which is basically what you have written, it needs to be
wher col_value >10 or col_value <10

Now, if +10 and -10 are your actual boundary values, another way you might want to try would be
ABS(col_val) >10

Try both ways.
Re: Case statement [message #597612 is a reply to message #597610] Mon, 07 October 2013 03:41 Go to previous messageGo to next message
pablolee
Messages: 2882
Registered: May 2007
Location: Scotland
Senior Member
davron0 wrote on Mon, 07 October 2013 09:37

I literally just replaced the CASE with OR as i was not sure how to write it, but will the OR fix my issue related to the Divisor being equal to Zero? thats where the original issues occured

Which is precisely why you should post the code. We cannot guess as to the multitude of potential errors that you may or may not have introduced into your code, post what you did - We are much more likely to see the problem (see my post above)
Re: Case statement [message #597613 is a reply to message #597610] Mon, 07 October 2013 03:43 Go to previous messageGo to next message
davron0
Messages: 12
Registered: October 2013
Junior Member
i'm not sure how to, where do i get the code and i will gladly post it... i know this is might be frustrating but i do appreciate the help
Re: Case statement [message #597614 is a reply to message #597613] Mon, 07 October 2013 03:49 Go to previous messageGo to next message
pablolee
Messages: 2882
Registered: May 2007
Location: Scotland
Senior Member
davron0 wrote on Mon, 07 October 2013 09:43
i'm not sure how to, where do i get the code and i will gladly post it... i know this is might be frustrating but i do appreciate the help

You've already posted the code several times... I'm confused as to why you are confused.
You changed your code to
Quote:
I literally just replaced the CASE with OR as i was not sure how to write it, snip

That's the code that I wanted you to post i.e. post the code that you ran (even if that code failed)
Re: Case statement [message #597615 is a reply to message #597614] Mon, 07 October 2013 03:54 Go to previous messageGo to next message
davron0
Messages: 12
Registered: October 2013
Junior Member
SELECT ALL AMS.EGALISATION.NPTF AS Fund,
AMS.EGALISATION.TPARTS AS Shareclass,
EGALISATION_A1.DATE_NAV AS "Current Day",
EGALISATION_A1.RNI_PART AS "Current Income",
AMS.EGALISATION.DATE_NAV AS "Previous Day",
AMS.EGALISATION.RNI_PART AS "Previous Income",
OR
WHEN AMS.EGALISATION.RNI_PART = 0
THEN 0
ELSE (EGALISATION_A1.RNI_PART - AMS.EGALISATION.RNI_PART) / AMS.EGALISATION.RNI_PART * 100
END AS "% Movement"
FROM AMS.EGALISATION,
AMS.EGALISATION EGALISATION_A1
WHERE (AMS.EGALISATION.NPTF = EGALISATION_A1.NPTF)
AND (AMS.EGALISATION.TPARTS = EGALISATION_A1.TPARTS)
AND (AMS.EGALISATION.CEGA = EGALISATION_A1.CEGA)
AND
OR
WHEN AMS.EGALISATION.RNI_PART = 0
THEN 0
ELSE (EGALISATION_A1.RNI_PART - AMS.EGALISATION.RNI_PART) / AMS.EGALISATION.RNI_PART * 100
END > 10
AND ((AMS.EGALISATION.NPTF LIKE 'S2%'
OR (AMS.EGALISATION.NPTF LIKE 'S1%'
AND (AMS.EGALISATION.NPTF NOT LIKE 'S25%')))
AND (AMS.EGALISATION.DATE_NAV = TRUNC(SysDate) - 4
AND EGALISATION_A1.DATE_NAV = TRUNC(SysDate) - 1)
AND AMS.EGALISATION.CEGA = 'GB')
ORDER BY AMS.EGALISATION.NPTF
Re: Case statement [message #597616 is a reply to message #597615] Mon, 07 October 2013 03:55 Go to previous messageGo to next message
davron0
Messages: 12
Registered: October 2013
Junior Member
like i said i dont know how to write the "OR" into it, as i know the above is not right at all
Re: Case statement [message #597618 is a reply to message #597616] Mon, 07 October 2013 04:02 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
You're using case to get around divisor = 0. So you need to or two case statements:
AND (CASE
     WHEN AMS.EGALISATION.RNI_PART = 0
     THEN 0
     ELSE (EGALISATION_A1.RNI_PART - AMS.EGALISATION.RNI_PART) / AMS.EGALISATION.RNI_PART * 100
     END > 10
     OR
     CASE
     WHEN AMS.EGALISATION.RNI_PART = 0
     THEN 0
     ELSE (EGALISATION_A1.RNI_PART - AMS.EGALISATION.RNI_PART) / AMS.EGALISATION.RNI_PART * 100
     END < -10
     )
Re: Case statement [message #597619 is a reply to message #597615] Mon, 07 October 2013 04:04 Go to previous messageGo to next message
pablolee
Messages: 2882
Registered: May 2007
Location: Scotland
Senior Member
Please use the code tags as requested. I've already posted a snippet of code as to how to use the OR operator.
Re: Case statement [message #597620 is a reply to message #597607] Mon, 07 October 2013 04:07 Go to previous messageGo to next message
Lalit Kumar B
Messages: 3174
Registered: May 2013
Location: World Wide on the Web
Senior Member
pablolee wrote on Mon, 07 October 2013 13:48
Not seeing the point of that at all Lalit. All you have done is replace one conditional structure with another.
In addition, you where clause in your demo would not meet requirements as the restriction should be on the calculation not he column


I agree, I was blind to OPs where clause, I just went ahead with LFs example code. Anyway, now I see the point that the SELECT and WHERE have same expression. If I tweak the same demo it should work(hope am not being blind this time again) -

Thanks Pablolee for pointing out that.

SQL> WITH TEST AS
  2   (SELECT -20 ID, 10 VAL
  3      FROM DUAL
  4    UNION
  5    SELECT -15, 0
  6      FROM DUAL
  7    UNION
  8    SELECT 5, 2
  9      FROM DUAL
 10    UNION
 11    SELECT 160, -10 FROM DUAL)
 12  SELECT ID, VAL, NVL(ID / DECODE(VAL, 0, NULL, VAL), 0) MY_OUT
 13    FROM TEST
 14   WHERE
 15  -- (ID < -10 OR ID > 10)
 16  (NVL(ID / DECODE(VAL, 0, NULL, VAL), 0) < -10 OR NVL(ID / DECODE(VAL, 0, NULL, VAL), 0) > 10);
 
        ID        VAL     MY_OUT
---------- ---------- ----------
       160        -10        -16


Regards,
Lalit
Re: Case statement [message #597621 is a reply to message #597615] Mon, 07 October 2013 04:07 Go to previous messageGo to next message
pablolee
Messages: 2882
Registered: May 2007
Location: Scotland
Senior Member
OK, now I see what you meant by replacing the CASE with an OR.
Way off base Wink

You're ringinal query is really close.
Try
SELECT egl.nptf AS fund, --the ALL is unneccessary
      egl.tparts AS shareclass,
      eg2.date_nav AS "Current Day",
      eg2.rni_part AS "Current Income",
      egl.date_nav AS "Previous Day",
      egl.rni_part AS "Previous Income",
      CASE WHEN egl.rni_part = 0
           THEN 0
           ELSE (eg2.rni_part - egl.rni_part) / egl.rni_part * 100
      END AS "% Movement"
FROM ams.egalisation  egl, --alias for column refs, makes the whole thing easier to read
     ams.egalisation egl2 --shorter, quicker to type, easier to read
WHERE egl.nptf = eg2.nptf
  AND egl.tparts = eg2.tparts
  AND egl.cega = eg2.cega
  AND ABS(CASE WHEN egl.rni_part = 0
           THEN 0
           ELSE (eg2.rni_part - egl.rni_part) / egl.rni_part * 100
       END) > 10
  AND (egl.nptf LIKE 'S2%'  
   OR egl.nptf LIKE 'S1%')
--  AND (egl.nptf NOT LIKE 'S25%'))) --If either of the above are true, then this cannot be true and is therefore unneccessary
  AND egl.date_nav = trunc(SYSDATE) - 4
  AND eg2.date_nav = trunc(SYSDATE) - 1
  AND egl.cega = 'GB'
  --Removed a lot of unnecessary parens and fixed the ones around the OR 
ORDER BY egl.nptf;

Note the formatting, the code tags, the simplified aliasing. I've also tweaked the where clause a bit because I think that it might have been a bit off.

ETA, Note Lalit's example. Ignore the fact that all he did was replace one conditional construct with a different one, that's not important. What is important is the structure of the predicates. I'd also point out that you have already included this sort of structure in your code i.e. where you are restricting the nptf column. Is this by any chance, someone else's code that you are trying to adapt?

[Updated on: Mon, 07 October 2013 04:10]

Report message to a moderator

Re: Case statement [message #597623 is a reply to message #597620] Mon, 07 October 2013 04:11 Go to previous messageGo to next message
pablolee
Messages: 2882
Registered: May 2007
Location: Scotland
Senior Member
Fair play Lalit. I still don't see the point in replacing the CASE with a DECODE.
Re: Case statement [message #597625 is a reply to message #597616] Mon, 07 October 2013 04:15 Go to previous messageGo to next message
davron0
Messages: 12
Registered: October 2013
Junior Member
Pablo has nailed it, thanks so much for your time guys really helpful sight

forgive my stupidity at times, new system + accountant = well you seen for yourself

Thanks again
Re: Case statement [message #597626 is a reply to message #597621] Mon, 07 October 2013 04:17 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
pablolee wrote on Mon, 07 October 2013 10:07
  AND (egl.nptf LIKE 'S2%'  
   OR egl.nptf LIKE 'S1%')
--  AND (egl.nptf NOT LIKE 'S25%'))) --If either of the above are true, then this cannot be true and is therefore unneccessary


The bit you commented out is necessary.

[Updated on: Mon, 07 October 2013 04:18]

Report message to a moderator

Re: Case statement [message #597627 is a reply to message #597626] Mon, 07 October 2013 04:19 Go to previous messageGo to next message
pablolee
Messages: 2882
Registered: May 2007
Location: Scotland
Senior Member
cookiemonster wrote on Mon, 07 October 2013 10:17
pablolee wrote on Mon, 07 October 2013 10:07
  AND (egl.nptf LIKE 'S2%'  
   OR egl.nptf LIKE 'S1%')
--  AND (egl.nptf NOT LIKE 'S25%'))) --If either of the above are true, then this cannot be true and is therefore unneccessary


The bit you commented out is necessary.

Bugger! Of course it is. Thanks cookie!
Re: Case statement [message #597629 is a reply to message #597627] Mon, 07 October 2013 04:21 Go to previous message
davron0
Messages: 12
Registered: October 2013
Junior Member
I left it in, like Cookie said it is required but thanks for the rest of it works a charm
Previous Topic: Find the names of all stored proc invoked on execution of the main api
Next Topic: Want to ZIP clob field in Oracle
Goto Forum:
  


Current Time: Wed Apr 24 19:48:39 CDT 2024