Home » SQL & PL/SQL » SQL & PL/SQL » Case statement (SQL Developer)
Case statement [message #597580] |
Mon, 07 October 2013 00:56 |
|
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 #597589 is a reply to message #597587] |
Mon, 07 October 2013 01:30 |
Lalit Kumar B
Messages: 3174 Registered: May 2013 Location: World Wide on the Web
|
Senior Member |
|
|
davron0 wrote on Mon, 07 October 2013 11:53my 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 |
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 #597597 is a reply to message #597595] |
Mon, 07 October 2013 01:55 |
Lalit Kumar B
Messages: 3174 Registered: May 2013 Location: World Wide on the Web
|
Senior Member |
|
|
davron0 wrote on Mon, 07 October 2013 12:19i 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 |
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 |
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 |
|
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 #597611 is a reply to message #597609] |
Mon, 07 October 2013 03:39 |
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 |
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 #597614 is a reply to message #597613] |
Mon, 07 October 2013 03:49 |
pablolee
Messages: 2882 Registered: May 2007 Location: Scotland
|
Senior Member |
|
|
davron0 wrote on Mon, 07 October 2013 09:43i'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 #597618 is a reply to message #597616] |
Mon, 07 October 2013 04:02 |
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 |
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 |
Lalit Kumar B
Messages: 3174 Registered: May 2013 Location: World Wide on the Web
|
Senior Member |
|
|
pablolee wrote on Mon, 07 October 2013 13:48Not 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 |
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
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 #597626 is a reply to message #597621] |
Mon, 07 October 2013 04:17 |
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 |
pablolee
Messages: 2882 Registered: May 2007 Location: Scotland
|
Senior Member |
|
|
cookiemonster wrote on Mon, 07 October 2013 10:17pablolee 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!
|
|
|
|
Goto Forum:
Current Time: Wed Apr 24 19:48:39 CDT 2024
|