using the variable from the case clause in "where" statment - sql

In my SQL query I have a CASE clause. How can I use the variable name from the CASE in where statment. This is my query
SElECT
a,
b,
CASE
WHEN AVG(CAST([x] as DECIMAL(9,2))) = 0
THEN 0
ELSE AVG(CAST([y] as DECIMAL(9,2))) / AVG(CAST([x] as DECIMAL(9,2)))
END AS z
FROM magic_table
WHERE z > 0
GROUP BY a,b
here I can not grab the z in where clause. But How can I do it ? is there any other way of doing it ?

As Panagiotis Kanavos already commented you cant use column alias in where statement but you can put your whole case statement in HAVING clause like so:
SElECT
a,
b,
CASE
WHEN AVG(CAST([x] as DECIMAL(9,2))) = 0
THEN 0
ELSE AVG(CAST([y] as DECIMAL(9,2))) / AVG(CAST([x] as DECIMAL(9,2)))
END AS z
FROM magic_table
GROUP BY a,b
HAVING CASE
WHEN AVG(CAST([x] as DECIMAL(9,2))) = 0
THEN 0
ELSE AVG(CAST([y] as DECIMAL(9,2))) / AVG(CAST([x] as DECIMAL(9,2)))
END > 0

Related

Use nested case, when and else condition in stored procedure

I want to execute a stored procedure with 4 input parameters:
int A, B, C, D
and need to execute as
A/B - C/D
but I have to handle Null and 0 to avoid divide by zero exception.
I was trying this approach, but that didn't work out:
case when D is null or D = 0
then case when B is null or B=0 then 0
else cast(A/B) end
case when C is null or C=0
case when B is null or B= 0, then 0
else cast( A/B) end
case when A is null or A=0
case when D is null or D= 0, then 0
else cast(C/D) end
case when B is null or B=0
case when D is null or D= 0, then 0
else cast(C/D) end
else cast (A/B - C/D) end as Result
Hmmm . . . I am guessing you really want - C/D if A/B is not well-defined.
If so, you don't need a case expression at all:
(coalesce(A / nullif(B, 0), 0) -
coalesce(C / nullif(D, 0), 0)
) as Result
Here we can use ISNULL function also
CASE WHEN ISNULL(B,0) > 0 THEN A/B ELSE 0 END)
-
(CASE WHEN ISNULL(D,0) > 0 THEN C/D ELSE 0 END)

posgresql exclude zero division error results

I am executing a query but for sum cases
SUM( CASE WHEN dismissal_kind = 'caught' THEN 1 ELSE 0 END )
this part of the code results into zero which causes zero division error.I am trying to not show result(not select) when
SUM( CASE WHEN dismissal_kind = 'caught' THEN 1 ELSE 0 END )
Pease help.
"""select distinct bowler as b,
count(bowler)/SUM( CASE WHEN dismissal_kind = 'caught' THEN 1 ELSE 0 END ) from deliveries
group by bowler; """
You can do it this way, by using case when:
In my example i put the default value to 0 but you can have a default value different depending on your use case
select distinct bowler as b,
case when SUM( CASE WHEN dismissal_kind = 'caught' THEN 1 ELSE 0 END ) <> 0
then
count(bowler)/SUM( CASE WHEN dismissal_kind = 'caught' THEN 1 ELSE 0 END )
else
0
end
from deliveries
group by bowler;
The simplest way is to remove the else 0:
SUM( CASE WHEN dismissal_kind = 'caught' THEN 1 END )
This returns NULL if nothing matches the condition. Dividing by NULL produces NULL and not an error.
For your query however, I recommend:
select bowler as b,
count(*) / nullif(count(*) filter (where dismissal_kind = 'caught'), 0)
from deliveries
group by bowler;
nullif() is another way to avoid division by zero. filter is the recommended (and standard) syntax for conditional aggregation.
If you want to filter out the rows that are null, you can include a having clause:
select bowler as b,
count(*) / nullif(count(*) filter (where dismissal_kind = 'caught'), 0)
from deliveries
group by bowler
having count(*) filter (where dismissal_kind = 'caught') > 0;

SQL Case with sum and normal value

Below is my SQL query
select
case when x < 2 then a
when x = 0 then Max(a) end a
,case when x < 2 then b
when x = 0 then Sum(b) end b
from T
How can we do this? I am using right now Union to get the required result. Looking for a better way to do this.
You can get these aggregate values into a variable and use it.
DECLARE #maxA int;
DECLARE #sumB int;
SELECT #maxA = max(a),#sumB = sum(b) FROM t;
SELECT CASE
WHEN x < 2 THEN a
WHEN x = 0 THEN #maxA
END a ,
CASE
WHEN x < 2 THEN b
WHEN x = 0 THEN #sumB
END b
FROM T
You can use CASE When conditions inside the Aggregate functions.
i.e.
SELECT SUM(CASE WHEN x < 2 THEN a WHEN x = 0 THEN #maxA END) AS sum_a

Using same calculation for different SQL Aliases

so I have two column aliases that are using the same calculation:
,case when bi.PolicyFeeFactor = 0
then 0
else
CAST(ROUND(nb.AnnualPolicyFee * bi.PolicyFeeFactor,2)AS DECIMAL(6,2))
end
as UNIT_POLFEE_Y
,case when bi.PolicyFeeFactor = 0
then 0
else
CAST(ROUND(nb.AnnualPolicyFee * bi.PolicyFeeFactor,2)AS DECIMAL(6,2))
end
as UNIT_PUPFEE_Y
I am looking for a way where I can just write the calculation once and create both column aliases from that one statement eg:
,case when bi.PolicyFeeFactor = 0
then 0
else
CAST(ROUND(nb.AnnualPolicyFee * bi.PolicyFeeFactor,2)AS DECIMAL(6,2))
end
as UNIT_PUPFEE_Y, UNIT_POLFEE_Y
Wrap it inside a subquery, ex
SELECT Result AS UNIT_PUPFEE_Y,
Result AS UNIT_POLFEE_Y
FROM
(
SELECT CASE .... END AS Result
FROM tableName
) s
You may write like this,
SELECT *,UNIT_PULFEE_Y AS UNIT_PUPFEE_Y FROM
(SELECT *
,case when bi.PolicyFeeFactor = 0 then 0 else CAST(ROUND(nb.AnnualPolicyFee * bi.PolicyFeeFactor,2)AS DECIMAL(6,2)) end as UNIT_PULFEE_Y
FROM Table )A

SQL qn:- Case expression

I have data in table a that i want to quench and create into another table b. Wondering how to do this. I was thinking of doing nested CASE expressions. But is this do-able?
For eg:-
Table a:-
S En Eg
-0.2 7888 99
90 9000 788
100 999 888
I want to create another table b, that does this:-
select
CASE WHEN S < 0 then (S+1/En-Eg)
ELSE (S-1/En-Eg)) END AS Z
from a
I also want to compare Z with other values:-
If z > 0 then 'Good'
else 'Bad'
Something like that, can i do this inside table b as well?
You could "reuse" the CASE expression if you performed it in a subquery:
SELECT z, CASE WHEN z > 0 THEN 'Good' ELSE 'Bad' END AS zdesc
FROM (
SELECT CASE WHEN S < 0
THEN (S + 1 / En - Eg)
ELSE (S - 1 / En - Eg) END AS z
FROM a
) b