Issue while creating case expression












0















I am facing issues when I try to create a case expression with a group function condition along with normal column conditions.



Table: STG




+ -------+--------+------+----------+
| Ref_ID | Actual | Paid | Reason |
+ -------+--------+------+----------+
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 480 | TRAINING |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
+ -------+--------+------+----------+


Already the code is like below:



Explanation: If Actual hrs per day exceeds 480 then that needs to be taken as 480. ie. 8hrs/day * 60 =480.
then the sum of actual is extended 1440 then that needs to be deducted from the sum of actual hrs.



In this same query, I have to sum the all actuals along with paid (paid hrs if reason is Training)



 SELECT
CASE WHEN (SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END))>1440 THEN
((SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END))-1440) ELSE 0
END SINGLE_RATE
FROM STG WHERE REF_ID='H1'
GROUP BY REF_ID;


I tried to modify like below:



SELECT
CASE WHEN (SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END)+(case when reason = 'training' then paid else 0 end ))>1440 THEN
((SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END)+(case when reason = 'training' then paid else 0 end ))-1440) ELSE 0
END SINGLE_RATE
FROM STG WHERE REF_ID='H1'
GROUP BY REF_ID;


but getting below error:



    ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
*Cause:
*Action:


Also tried like:



SELECT
(sum ( (CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END) + case when reason = 'training' then paid else 0 end )-1440) SINGLE_RATE
FROM STG WHERE REF_ID='H1'
GROUP BY REF_ID
having sum ( (CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END) + case when reason = 'training' then paid else 0 end )>1440;


but the paid amount is not getting calculated. Only actual is added.



Please give your suggestions.










share|improve this question

























  • You could refer this: stackoverflow.com/questions/11325268/…

    – Namandeep_Kaur
    Nov 22 '18 at 18:11













  • Thank you for your quick response Namandeep..

    – user10692352
    Nov 22 '18 at 18:17











  • Edited my question. Please help me.

    – user10692352
    Nov 22 '18 at 18:26











  • What issue are you having? What have you tried to do and what was wrong with it? You can include your desired result in your question; and if you have a query that gets the wrong results, you can include that too, and explain what is wrong with it.

    – Alex Poole
    Nov 22 '18 at 18:31











  • Thank you Alex for edited my question in perfect way.

    – user10692352
    Nov 22 '18 at 18:33
















0















I am facing issues when I try to create a case expression with a group function condition along with normal column conditions.



Table: STG




+ -------+--------+------+----------+
| Ref_ID | Actual | Paid | Reason |
+ -------+--------+------+----------+
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 480 | TRAINING |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
+ -------+--------+------+----------+


Already the code is like below:



Explanation: If Actual hrs per day exceeds 480 then that needs to be taken as 480. ie. 8hrs/day * 60 =480.
then the sum of actual is extended 1440 then that needs to be deducted from the sum of actual hrs.



In this same query, I have to sum the all actuals along with paid (paid hrs if reason is Training)



 SELECT
CASE WHEN (SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END))>1440 THEN
((SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END))-1440) ELSE 0
END SINGLE_RATE
FROM STG WHERE REF_ID='H1'
GROUP BY REF_ID;


I tried to modify like below:



SELECT
CASE WHEN (SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END)+(case when reason = 'training' then paid else 0 end ))>1440 THEN
((SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END)+(case when reason = 'training' then paid else 0 end ))-1440) ELSE 0
END SINGLE_RATE
FROM STG WHERE REF_ID='H1'
GROUP BY REF_ID;


but getting below error:



    ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
*Cause:
*Action:


Also tried like:



SELECT
(sum ( (CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END) + case when reason = 'training' then paid else 0 end )-1440) SINGLE_RATE
FROM STG WHERE REF_ID='H1'
GROUP BY REF_ID
having sum ( (CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END) + case when reason = 'training' then paid else 0 end )>1440;


but the paid amount is not getting calculated. Only actual is added.



Please give your suggestions.










share|improve this question

























  • You could refer this: stackoverflow.com/questions/11325268/…

    – Namandeep_Kaur
    Nov 22 '18 at 18:11













  • Thank you for your quick response Namandeep..

    – user10692352
    Nov 22 '18 at 18:17











  • Edited my question. Please help me.

    – user10692352
    Nov 22 '18 at 18:26











  • What issue are you having? What have you tried to do and what was wrong with it? You can include your desired result in your question; and if you have a query that gets the wrong results, you can include that too, and explain what is wrong with it.

    – Alex Poole
    Nov 22 '18 at 18:31











  • Thank you Alex for edited my question in perfect way.

    – user10692352
    Nov 22 '18 at 18:33














0












0








0








I am facing issues when I try to create a case expression with a group function condition along with normal column conditions.



Table: STG




+ -------+--------+------+----------+
| Ref_ID | Actual | Paid | Reason |
+ -------+--------+------+----------+
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 480 | TRAINING |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
+ -------+--------+------+----------+


Already the code is like below:



Explanation: If Actual hrs per day exceeds 480 then that needs to be taken as 480. ie. 8hrs/day * 60 =480.
then the sum of actual is extended 1440 then that needs to be deducted from the sum of actual hrs.



In this same query, I have to sum the all actuals along with paid (paid hrs if reason is Training)



 SELECT
CASE WHEN (SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END))>1440 THEN
((SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END))-1440) ELSE 0
END SINGLE_RATE
FROM STG WHERE REF_ID='H1'
GROUP BY REF_ID;


I tried to modify like below:



SELECT
CASE WHEN (SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END)+(case when reason = 'training' then paid else 0 end ))>1440 THEN
((SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END)+(case when reason = 'training' then paid else 0 end ))-1440) ELSE 0
END SINGLE_RATE
FROM STG WHERE REF_ID='H1'
GROUP BY REF_ID;


but getting below error:



    ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
*Cause:
*Action:


Also tried like:



SELECT
(sum ( (CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END) + case when reason = 'training' then paid else 0 end )-1440) SINGLE_RATE
FROM STG WHERE REF_ID='H1'
GROUP BY REF_ID
having sum ( (CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END) + case when reason = 'training' then paid else 0 end )>1440;


but the paid amount is not getting calculated. Only actual is added.



Please give your suggestions.










share|improve this question
















I am facing issues when I try to create a case expression with a group function condition along with normal column conditions.



Table: STG




+ -------+--------+------+----------+
| Ref_ID | Actual | Paid | Reason |
+ -------+--------+------+----------+
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 0 | 480 | TRAINING |
| H1 | 0 | 0 | |
| H1 | 360 | 0 | |
| H1 | 360 | 0 | |
+ -------+--------+------+----------+


Already the code is like below:



Explanation: If Actual hrs per day exceeds 480 then that needs to be taken as 480. ie. 8hrs/day * 60 =480.
then the sum of actual is extended 1440 then that needs to be deducted from the sum of actual hrs.



In this same query, I have to sum the all actuals along with paid (paid hrs if reason is Training)



 SELECT
CASE WHEN (SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END))>1440 THEN
((SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END))-1440) ELSE 0
END SINGLE_RATE
FROM STG WHERE REF_ID='H1'
GROUP BY REF_ID;


I tried to modify like below:



SELECT
CASE WHEN (SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END)+(case when reason = 'training' then paid else 0 end ))>1440 THEN
((SUM(CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END)+(case when reason = 'training' then paid else 0 end ))-1440) ELSE 0
END SINGLE_RATE
FROM STG WHERE REF_ID='H1'
GROUP BY REF_ID;


but getting below error:



    ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
*Cause:
*Action:


Also tried like:



SELECT
(sum ( (CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END) + case when reason = 'training' then paid else 0 end )-1440) SINGLE_RATE
FROM STG WHERE REF_ID='H1'
GROUP BY REF_ID
having sum ( (CASE WHEN (ACTUAL)>480 THEN 480 ELSE (ACTUAL) END) + case when reason = 'training' then paid else 0 end )>1440;


but the paid amount is not getting calculated. Only actual is added.



Please give your suggestions.







sql oracle






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 8:22









Thorsten Kettner

51.7k32642




51.7k32642










asked Nov 22 '18 at 18:10









user10692352user10692352

43




43













  • You could refer this: stackoverflow.com/questions/11325268/…

    – Namandeep_Kaur
    Nov 22 '18 at 18:11













  • Thank you for your quick response Namandeep..

    – user10692352
    Nov 22 '18 at 18:17











  • Edited my question. Please help me.

    – user10692352
    Nov 22 '18 at 18:26











  • What issue are you having? What have you tried to do and what was wrong with it? You can include your desired result in your question; and if you have a query that gets the wrong results, you can include that too, and explain what is wrong with it.

    – Alex Poole
    Nov 22 '18 at 18:31











  • Thank you Alex for edited my question in perfect way.

    – user10692352
    Nov 22 '18 at 18:33



















  • You could refer this: stackoverflow.com/questions/11325268/…

    – Namandeep_Kaur
    Nov 22 '18 at 18:11













  • Thank you for your quick response Namandeep..

    – user10692352
    Nov 22 '18 at 18:17











  • Edited my question. Please help me.

    – user10692352
    Nov 22 '18 at 18:26











  • What issue are you having? What have you tried to do and what was wrong with it? You can include your desired result in your question; and if you have a query that gets the wrong results, you can include that too, and explain what is wrong with it.

    – Alex Poole
    Nov 22 '18 at 18:31











  • Thank you Alex for edited my question in perfect way.

    – user10692352
    Nov 22 '18 at 18:33

















You could refer this: stackoverflow.com/questions/11325268/…

– Namandeep_Kaur
Nov 22 '18 at 18:11







You could refer this: stackoverflow.com/questions/11325268/…

– Namandeep_Kaur
Nov 22 '18 at 18:11















Thank you for your quick response Namandeep..

– user10692352
Nov 22 '18 at 18:17





Thank you for your quick response Namandeep..

– user10692352
Nov 22 '18 at 18:17













Edited my question. Please help me.

– user10692352
Nov 22 '18 at 18:26





Edited my question. Please help me.

– user10692352
Nov 22 '18 at 18:26













What issue are you having? What have you tried to do and what was wrong with it? You can include your desired result in your question; and if you have a query that gets the wrong results, you can include that too, and explain what is wrong with it.

– Alex Poole
Nov 22 '18 at 18:31





What issue are you having? What have you tried to do and what was wrong with it? You can include your desired result in your question; and if you have a query that gets the wrong results, you can include that too, and explain what is wrong with it.

– Alex Poole
Nov 22 '18 at 18:31













Thank you Alex for edited my question in perfect way.

– user10692352
Nov 22 '18 at 18:33





Thank you Alex for edited my question in perfect way.

– user10692352
Nov 22 '18 at 18:33












1 Answer
1






active

oldest

votes


















2














From your business rules, you always want to include actual in the sum() calculation but only include paid when the reason is 'training'. That rule is quite easy to express in a case statement. In addition you have a cap that actual cannot exceed 480. That rule can be satisfied with a least() function:



select ref_id
, sum ( least(actual, 480) + case when reason = 'training' then paid else 0 end ) as tot
from stg
group by ref_id
/


To be frank I am still not clear what you are trying to achieve with the 1440; life would be easier if you had posted some sample data which covered all the cases you wanted to handle and your desired output derived from that sample data. But I am going to guess anyway:



with cte as (
select ref_id
, sum ( least(actual, 480) + case when reason = 'training' then paid else 0 end ) as tot
from stg
group by ref_id
)
select ref_id
case
when tot <= 1440 then tot
else tot - 1440
end as adjusted_tot
from cte
/




As before, if this does not provide the answer you want please edit your question. The clearer your requirement the more likely you are to get a timely answer.






share|improve this answer


























  • Thank you APC. As I don't have office laptop, I just tried this with my personal laptop. The results comes as I expected. but, I will try this by tomorrow on office and will tell you whether it works out. Sorry for making you confuse. but, not sure how to explain my question. So that, so much confusion on my question. Thank you so much for your response.

    – user10692352
    Nov 22 '18 at 19:06













  • Hi APC, I have tried with your suggestion code. but that is not workout that what I want. Also edited my questions. but check and give your suggestion.

    – user10692352
    Nov 23 '18 at 7:10











  • I have tried like below. It gives the expected result : 6240. But, I have to try this inside package. Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) ) as tot --sum(paid) as paid from stg where payroll_ref='H1' group by ref_id ), cte1 as ( select ref_id, sum(paid) as paid from stg where ref_id='H1' and reason='TRAINING' group by ref_id ) select case when (cte.tot+cte1.paid) <= 1440 then tot else (cte.tot+cte1.paid) - 1440 end as single_rate from cte, cte1;

    – user10692352
    Nov 23 '18 at 9:28











  • I just noticed the case on reason after Thorsten's suggestion. So, I just changed the reason as UPPER case in the code which you have suggested. now, thats working as expected. I will try this in package. Really Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) + case when reason='TRAINING' then paid else 0 end ) as tot from stg where ref_id='H1' group by ref_id ) select ref_id, case when tot <= 1440 then tot else tot - 1440 end as adjusted_tot from cte;

    – user10692352
    Nov 23 '18 at 9:37











  • We can call SQL in packaged procedures. It's merely a matter of selecting INTO variables (or a record variable) which matches the projection of the query. The PL/SQL documentation and indeed this very site are littered with examples, if you cannot figure it out for yourself.

    – APC
    Nov 23 '18 at 9:41











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436302%2fissue-while-creating-case-expression%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














From your business rules, you always want to include actual in the sum() calculation but only include paid when the reason is 'training'. That rule is quite easy to express in a case statement. In addition you have a cap that actual cannot exceed 480. That rule can be satisfied with a least() function:



select ref_id
, sum ( least(actual, 480) + case when reason = 'training' then paid else 0 end ) as tot
from stg
group by ref_id
/


To be frank I am still not clear what you are trying to achieve with the 1440; life would be easier if you had posted some sample data which covered all the cases you wanted to handle and your desired output derived from that sample data. But I am going to guess anyway:



with cte as (
select ref_id
, sum ( least(actual, 480) + case when reason = 'training' then paid else 0 end ) as tot
from stg
group by ref_id
)
select ref_id
case
when tot <= 1440 then tot
else tot - 1440
end as adjusted_tot
from cte
/




As before, if this does not provide the answer you want please edit your question. The clearer your requirement the more likely you are to get a timely answer.






share|improve this answer


























  • Thank you APC. As I don't have office laptop, I just tried this with my personal laptop. The results comes as I expected. but, I will try this by tomorrow on office and will tell you whether it works out. Sorry for making you confuse. but, not sure how to explain my question. So that, so much confusion on my question. Thank you so much for your response.

    – user10692352
    Nov 22 '18 at 19:06













  • Hi APC, I have tried with your suggestion code. but that is not workout that what I want. Also edited my questions. but check and give your suggestion.

    – user10692352
    Nov 23 '18 at 7:10











  • I have tried like below. It gives the expected result : 6240. But, I have to try this inside package. Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) ) as tot --sum(paid) as paid from stg where payroll_ref='H1' group by ref_id ), cte1 as ( select ref_id, sum(paid) as paid from stg where ref_id='H1' and reason='TRAINING' group by ref_id ) select case when (cte.tot+cte1.paid) <= 1440 then tot else (cte.tot+cte1.paid) - 1440 end as single_rate from cte, cte1;

    – user10692352
    Nov 23 '18 at 9:28











  • I just noticed the case on reason after Thorsten's suggestion. So, I just changed the reason as UPPER case in the code which you have suggested. now, thats working as expected. I will try this in package. Really Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) + case when reason='TRAINING' then paid else 0 end ) as tot from stg where ref_id='H1' group by ref_id ) select ref_id, case when tot <= 1440 then tot else tot - 1440 end as adjusted_tot from cte;

    – user10692352
    Nov 23 '18 at 9:37











  • We can call SQL in packaged procedures. It's merely a matter of selecting INTO variables (or a record variable) which matches the projection of the query. The PL/SQL documentation and indeed this very site are littered with examples, if you cannot figure it out for yourself.

    – APC
    Nov 23 '18 at 9:41
















2














From your business rules, you always want to include actual in the sum() calculation but only include paid when the reason is 'training'. That rule is quite easy to express in a case statement. In addition you have a cap that actual cannot exceed 480. That rule can be satisfied with a least() function:



select ref_id
, sum ( least(actual, 480) + case when reason = 'training' then paid else 0 end ) as tot
from stg
group by ref_id
/


To be frank I am still not clear what you are trying to achieve with the 1440; life would be easier if you had posted some sample data which covered all the cases you wanted to handle and your desired output derived from that sample data. But I am going to guess anyway:



with cte as (
select ref_id
, sum ( least(actual, 480) + case when reason = 'training' then paid else 0 end ) as tot
from stg
group by ref_id
)
select ref_id
case
when tot <= 1440 then tot
else tot - 1440
end as adjusted_tot
from cte
/




As before, if this does not provide the answer you want please edit your question. The clearer your requirement the more likely you are to get a timely answer.






share|improve this answer


























  • Thank you APC. As I don't have office laptop, I just tried this with my personal laptop. The results comes as I expected. but, I will try this by tomorrow on office and will tell you whether it works out. Sorry for making you confuse. but, not sure how to explain my question. So that, so much confusion on my question. Thank you so much for your response.

    – user10692352
    Nov 22 '18 at 19:06













  • Hi APC, I have tried with your suggestion code. but that is not workout that what I want. Also edited my questions. but check and give your suggestion.

    – user10692352
    Nov 23 '18 at 7:10











  • I have tried like below. It gives the expected result : 6240. But, I have to try this inside package. Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) ) as tot --sum(paid) as paid from stg where payroll_ref='H1' group by ref_id ), cte1 as ( select ref_id, sum(paid) as paid from stg where ref_id='H1' and reason='TRAINING' group by ref_id ) select case when (cte.tot+cte1.paid) <= 1440 then tot else (cte.tot+cte1.paid) - 1440 end as single_rate from cte, cte1;

    – user10692352
    Nov 23 '18 at 9:28











  • I just noticed the case on reason after Thorsten's suggestion. So, I just changed the reason as UPPER case in the code which you have suggested. now, thats working as expected. I will try this in package. Really Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) + case when reason='TRAINING' then paid else 0 end ) as tot from stg where ref_id='H1' group by ref_id ) select ref_id, case when tot <= 1440 then tot else tot - 1440 end as adjusted_tot from cte;

    – user10692352
    Nov 23 '18 at 9:37











  • We can call SQL in packaged procedures. It's merely a matter of selecting INTO variables (or a record variable) which matches the projection of the query. The PL/SQL documentation and indeed this very site are littered with examples, if you cannot figure it out for yourself.

    – APC
    Nov 23 '18 at 9:41














2












2








2







From your business rules, you always want to include actual in the sum() calculation but only include paid when the reason is 'training'. That rule is quite easy to express in a case statement. In addition you have a cap that actual cannot exceed 480. That rule can be satisfied with a least() function:



select ref_id
, sum ( least(actual, 480) + case when reason = 'training' then paid else 0 end ) as tot
from stg
group by ref_id
/


To be frank I am still not clear what you are trying to achieve with the 1440; life would be easier if you had posted some sample data which covered all the cases you wanted to handle and your desired output derived from that sample data. But I am going to guess anyway:



with cte as (
select ref_id
, sum ( least(actual, 480) + case when reason = 'training' then paid else 0 end ) as tot
from stg
group by ref_id
)
select ref_id
case
when tot <= 1440 then tot
else tot - 1440
end as adjusted_tot
from cte
/




As before, if this does not provide the answer you want please edit your question. The clearer your requirement the more likely you are to get a timely answer.






share|improve this answer















From your business rules, you always want to include actual in the sum() calculation but only include paid when the reason is 'training'. That rule is quite easy to express in a case statement. In addition you have a cap that actual cannot exceed 480. That rule can be satisfied with a least() function:



select ref_id
, sum ( least(actual, 480) + case when reason = 'training' then paid else 0 end ) as tot
from stg
group by ref_id
/


To be frank I am still not clear what you are trying to achieve with the 1440; life would be easier if you had posted some sample data which covered all the cases you wanted to handle and your desired output derived from that sample data. But I am going to guess anyway:



with cte as (
select ref_id
, sum ( least(actual, 480) + case when reason = 'training' then paid else 0 end ) as tot
from stg
group by ref_id
)
select ref_id
case
when tot <= 1440 then tot
else tot - 1440
end as adjusted_tot
from cte
/




As before, if this does not provide the answer you want please edit your question. The clearer your requirement the more likely you are to get a timely answer.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 23 '18 at 8:12

























answered Nov 22 '18 at 18:54









APCAPC

119k15118229




119k15118229













  • Thank you APC. As I don't have office laptop, I just tried this with my personal laptop. The results comes as I expected. but, I will try this by tomorrow on office and will tell you whether it works out. Sorry for making you confuse. but, not sure how to explain my question. So that, so much confusion on my question. Thank you so much for your response.

    – user10692352
    Nov 22 '18 at 19:06













  • Hi APC, I have tried with your suggestion code. but that is not workout that what I want. Also edited my questions. but check and give your suggestion.

    – user10692352
    Nov 23 '18 at 7:10











  • I have tried like below. It gives the expected result : 6240. But, I have to try this inside package. Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) ) as tot --sum(paid) as paid from stg where payroll_ref='H1' group by ref_id ), cte1 as ( select ref_id, sum(paid) as paid from stg where ref_id='H1' and reason='TRAINING' group by ref_id ) select case when (cte.tot+cte1.paid) <= 1440 then tot else (cte.tot+cte1.paid) - 1440 end as single_rate from cte, cte1;

    – user10692352
    Nov 23 '18 at 9:28











  • I just noticed the case on reason after Thorsten's suggestion. So, I just changed the reason as UPPER case in the code which you have suggested. now, thats working as expected. I will try this in package. Really Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) + case when reason='TRAINING' then paid else 0 end ) as tot from stg where ref_id='H1' group by ref_id ) select ref_id, case when tot <= 1440 then tot else tot - 1440 end as adjusted_tot from cte;

    – user10692352
    Nov 23 '18 at 9:37











  • We can call SQL in packaged procedures. It's merely a matter of selecting INTO variables (or a record variable) which matches the projection of the query. The PL/SQL documentation and indeed this very site are littered with examples, if you cannot figure it out for yourself.

    – APC
    Nov 23 '18 at 9:41



















  • Thank you APC. As I don't have office laptop, I just tried this with my personal laptop. The results comes as I expected. but, I will try this by tomorrow on office and will tell you whether it works out. Sorry for making you confuse. but, not sure how to explain my question. So that, so much confusion on my question. Thank you so much for your response.

    – user10692352
    Nov 22 '18 at 19:06













  • Hi APC, I have tried with your suggestion code. but that is not workout that what I want. Also edited my questions. but check and give your suggestion.

    – user10692352
    Nov 23 '18 at 7:10











  • I have tried like below. It gives the expected result : 6240. But, I have to try this inside package. Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) ) as tot --sum(paid) as paid from stg where payroll_ref='H1' group by ref_id ), cte1 as ( select ref_id, sum(paid) as paid from stg where ref_id='H1' and reason='TRAINING' group by ref_id ) select case when (cte.tot+cte1.paid) <= 1440 then tot else (cte.tot+cte1.paid) - 1440 end as single_rate from cte, cte1;

    – user10692352
    Nov 23 '18 at 9:28











  • I just noticed the case on reason after Thorsten's suggestion. So, I just changed the reason as UPPER case in the code which you have suggested. now, thats working as expected. I will try this in package. Really Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) + case when reason='TRAINING' then paid else 0 end ) as tot from stg where ref_id='H1' group by ref_id ) select ref_id, case when tot <= 1440 then tot else tot - 1440 end as adjusted_tot from cte;

    – user10692352
    Nov 23 '18 at 9:37











  • We can call SQL in packaged procedures. It's merely a matter of selecting INTO variables (or a record variable) which matches the projection of the query. The PL/SQL documentation and indeed this very site are littered with examples, if you cannot figure it out for yourself.

    – APC
    Nov 23 '18 at 9:41

















Thank you APC. As I don't have office laptop, I just tried this with my personal laptop. The results comes as I expected. but, I will try this by tomorrow on office and will tell you whether it works out. Sorry for making you confuse. but, not sure how to explain my question. So that, so much confusion on my question. Thank you so much for your response.

– user10692352
Nov 22 '18 at 19:06







Thank you APC. As I don't have office laptop, I just tried this with my personal laptop. The results comes as I expected. but, I will try this by tomorrow on office and will tell you whether it works out. Sorry for making you confuse. but, not sure how to explain my question. So that, so much confusion on my question. Thank you so much for your response.

– user10692352
Nov 22 '18 at 19:06















Hi APC, I have tried with your suggestion code. but that is not workout that what I want. Also edited my questions. but check and give your suggestion.

– user10692352
Nov 23 '18 at 7:10





Hi APC, I have tried with your suggestion code. but that is not workout that what I want. Also edited my questions. but check and give your suggestion.

– user10692352
Nov 23 '18 at 7:10













I have tried like below. It gives the expected result : 6240. But, I have to try this inside package. Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) ) as tot --sum(paid) as paid from stg where payroll_ref='H1' group by ref_id ), cte1 as ( select ref_id, sum(paid) as paid from stg where ref_id='H1' and reason='TRAINING' group by ref_id ) select case when (cte.tot+cte1.paid) <= 1440 then tot else (cte.tot+cte1.paid) - 1440 end as single_rate from cte, cte1;

– user10692352
Nov 23 '18 at 9:28





I have tried like below. It gives the expected result : 6240. But, I have to try this inside package. Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) ) as tot --sum(paid) as paid from stg where payroll_ref='H1' group by ref_id ), cte1 as ( select ref_id, sum(paid) as paid from stg where ref_id='H1' and reason='TRAINING' group by ref_id ) select case when (cte.tot+cte1.paid) <= 1440 then tot else (cte.tot+cte1.paid) - 1440 end as single_rate from cte, cte1;

– user10692352
Nov 23 '18 at 9:28













I just noticed the case on reason after Thorsten's suggestion. So, I just changed the reason as UPPER case in the code which you have suggested. now, thats working as expected. I will try this in package. Really Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) + case when reason='TRAINING' then paid else 0 end ) as tot from stg where ref_id='H1' group by ref_id ) select ref_id, case when tot <= 1440 then tot else tot - 1440 end as adjusted_tot from cte;

– user10692352
Nov 23 '18 at 9:37





I just noticed the case on reason after Thorsten's suggestion. So, I just changed the reason as UPPER case in the code which you have suggested. now, thats working as expected. I will try this in package. Really Thank you APC. with cte as ( select ref_id , sum ( least(actual, 480) + case when reason='TRAINING' then paid else 0 end ) as tot from stg where ref_id='H1' group by ref_id ) select ref_id, case when tot <= 1440 then tot else tot - 1440 end as adjusted_tot from cte;

– user10692352
Nov 23 '18 at 9:37













We can call SQL in packaged procedures. It's merely a matter of selecting INTO variables (or a record variable) which matches the projection of the query. The PL/SQL documentation and indeed this very site are littered with examples, if you cannot figure it out for yourself.

– APC
Nov 23 '18 at 9:41





We can call SQL in packaged procedures. It's merely a matter of selecting INTO variables (or a record variable) which matches the projection of the query. The PL/SQL documentation and indeed this very site are littered with examples, if you cannot figure it out for yourself.

– APC
Nov 23 '18 at 9:41




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436302%2fissue-while-creating-case-expression%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

To store a contact into the json file from server.js file using a class in NodeJS

Redirect URL with Chrome Remote Debugging Android Devices

Dieringhausen