Need to get null back rather than divide by zero - sql

I had to change my old query to a new query to get the correct results. My old query used to return a null in the denominator, so I didn't have to worry about divide by zero, the new query returns divide my zero for 'M' (R_NTWK_CHNNL), but for 'S' or R, i don't have a zero denominator. What can I do to get a null denominator in query 2? The table definition didn't change and wondering why now I don't get a null denominator when 'M' has nothing in it. Please also, how would I add nullif to the query 2? Thank you very much.
Old query
select SUM(CASE WHEN (GNRC_CD in ('O') and R_NTWK_CHNNL = 'M') then (CLNT_NET_DUE_AMT + NBNR_CLNT_NET_DUE_AMT) else 0 end ) / sUM(CLMS) from #Clms_SMRY where SRVC_DT between #CurrentBeginDate and #CurrentEndDate)
New query
select SUM(CASE WHEN (GNRC_CD in ('O') ) and R_NTWK_CHNNL = 'M' then (CLNT_NET_DUE_AMT + NBNR_CLNT_NET_DUE_AMT) else 0 end ) / cast(SUM(CASE WHEN GNRC_CD in ('O') and R_NTWK_CHNNL = 'M' then (CLMS) end ) as float) from #Clms_Smry where SRVC_DT between #CurrentBeginDate and #CurrentEndDate),

Use NULLIF():
select (SUM(CASE WHEN (GNRC_CD in ('O') and R_NTWK_CHNNL = 'M') then (CLNT_NET_DUE_AMT + NBNR_CLNT_NET_DUE_AMT) else 0 end ) /
NULLIF(SUM(CLMS), 0)
)
from #Clms_SMRY
where SRVC_DT between #CurrentBeginDate and #CurrentEndDate)

Related

How to Round Decimal Result of a Calculated Column in Oracle SQL

I have a calculated column in Oracle that returns a number that is very long because of decimals (ex: 200000.0044068030021345452041589203332645).
Is there a way to convert this to say 200000.00? I tried Round, TO_DECIMAL, CAST. But nothing seems to work.
SELECT
CASE
WHEN TRD = 'FUT'
THEN
CASE
WHEN BUY_SELL = 'BUY'
THEN CUR / PRC
ELSE -CUR / PRC
END
ELSE NULL
END AS UNITS
FROM LAN.Details
use round
select round(200000.0044068030021345452041589203332645,2) from dual
so in your query
SELECT
CASE
WHEN TRD = 'FUT'
THEN
CASE
WHEN BUY_SELL = 'BUY'
THEN round( CUR / PRC ,2)
ELSE round(-CUR / PRC,2)
END
ELSE NULL
END AS UNITS
FROM LAN.Details

AVG function is not working perfectly in SQL Server

I have 2 database, one in Mysql and a second in SQL Server. In these 2 databases, I have a table tb_Episode, both databases have same records.
When I run this query in Mysql, it returns a result of 5.1582, whereas in SQL Server, it returns 5.
Why am I getting different results? I use this query - can anyone please help me, how can I resolve this error?
SELECT
AVG(CASE
WHEN (SN_Ep = '1' AND MonthEnd = '2017-04')
THEN SN_Visits
ELSE NULL
END) AS SNVisitsSNEps_2017_04
FROM
tb_Episode
WHERE
CustID = '27'
AND PayerType = 'Ep'
AND BranchID IN (238, 239, 240, 241)
In SQL Server the return data-type of AVG() is determined by the input data-type.
https://learn.microsoft.com/en-us/sql/t-sql/functions/avg-transact-sql
If you average a column of integers, the result will be an integer. If you want the result to be a different data-type, cast the input to be that data-type.
As an example...
AVG(
CAST(
CASE when (SN_Ep = '1' and MonthEnd='2017-04') then SN_Visits ELSE NULL END)
AS
DECIMAL(18,10)
)
)
Please try like this -
AVG(
CASE when (SN_Ep = '1' and MonthEnd='2017-04') then SN_Visits * 1. ELSE NULL END)
)
Some guidance for both databases:
else NULL is redundant.
If a value is a number, don't compare it to a string.
Then, you want to convert the integer type to a number for SQL Server. A simple way is to multiply by 1.0.
I would suggest for both:
SELECT AVG(CASE when SN_Ep = 1 and MonthEnd = '2017-04' THEN SN_Visits * 1.0 END) as SNVisitsSNEps_2017_04
FROM tb_Episode
WHERE CustID = 27 AND
PayerType = 'Ep' AND
BranchID IN (238, 239, 240, 241) ;

Work out percentage count using SQL CASE statement

I have the following code which tells me which line items are in and out of SLA.
How can I turn that into a %, so for example when I add them together it will show 98% SLA Met.
,CASE
WHEN m.COMPLETED_DT is NULL THEN ''
WHEN m.COMPLETED_DT <= m.SLA_ADJUSTED_DT THEN 'SLA Met'
WHEN m.SLA_ADJUSTED_DT IS NULL THEN 'SLA Met'
ELSE 'SLA Missed' END AS "SLA Desc"
If I had the result already, I think it would look something like...
SELECT (count(*) * 100 / (select count(*) FROM testtable)) AS YesSLA
FROM testtable where SLA='Yes';
I am not sure how to integrate that with my current statement, I don't believe I can reference the AS SLA Desc in a new statement.
Does this do what you want?
select 100 * avg(case when m.completed_dt <= m.SLA_ADJUSTED_DT or m.SLA_ADJUSTED_DT is null
then 1.0 else 0
end)
from testtable
where SLA = 'Yes';
The code below calculates the % met SLA out of 100 by counting only values that met SLA and then dividing by the total opportunities.
DECLARE #Data TABLE (COMPLETED_DT DATETIME, SLA_ADJUSTED_DT DATETIME)
INSERT #Data VALUES ('5/5/2014', '5/6/2014'), ('5/6/2014', '5/6/2014'), ('5/7/2014', '5/6/2014')
SELECT
CONVERT(FLOAT, SUM(CASE WHEN COMPLETED_DT <= SLA_ADJUSTED_DT THEN 1 ELSE 0 END)) * 100 / COUNT(1) AS [% Met SLA]
FROM #Data
Output
% Met SLA
----------------------
66.6666666666667

Average without calculate zero

I have some fields in the table, need to average those fields.
Then I run this syntax, because I don't want to calculate 0 (zero) value.
SELECT myDate, AVG(CASE myField1 WHEN 0 THEN NULL ELSE myField1 END) AS avgmyField1
FROM myTable WHERE myDate = '2014-06-01'
On my syntax, the average calculation means.. Make zero value to null.
My question is, How if all values are zero...?
Thank you.
Then you get NULL.
If you want zero instead, use COALESCE:
COALESCE( AVG(CASE myField1 WHEN 0 THEN NULL ELSE myField1 END) , 0)
Average will not use nullvalues to calculate an average value
IsNull or Coalesce can be used to change null values to different values.
This script will change 0 to null and take the average value:
SELECT IsNull(AVG(NullIf(val,0)), 0)
FROM
(Values(5),(7),(0)) tbl(val)
Since 0 is excluded the result is 6
You could also do this:
SELECT myDate, COALESCE(AVG(myField1), 0) AS avgmyField1
FROM myTable WHERE myDate = '2014-06-01' and myField1 <> 0

MySQL using calculated return values to calculate other values

Let's say I have a select Statement with the following:
SUM(st.tafPoints/200) as totalFriendReferrals,
SUM(CASE WHEN st.gender = "m" THEN st.tafPoints/200 ELSE 0 END) as maleFriendReferrals,
SUM(CASE WHEN st.gender = "f" THEN st.tafPoints/200 ELSE 0 END) as femaleFriendReferrals
I need to calculate the percentage of maleFriendReferrals based on the totalFriendReferrals. These are both derived (ie, not originally in the list of columns) values. So if I try to do something like:
CONCAT( (maleFriendReferrals/totalFriendReferrals) *100 , '%') as malePercentReferrals
But I get an error:
Unknown column 'maleFriendReferrals' in 'field list' – 1 ms
Is there a way to do this easily? I need to be able to do this within the query itself, and not have to loop through my results to calculate percentages.
You should put the original query to a subquery
SELECT CONCAT( (maleFriendReferrals/totalFriendReferrals) *100 , '%') as malePercentReferrals
FROM
(SELECT
SUM(st.tafPoints/200) as totalFriendReferrals,
SUM(CASE WHEN st.gender = "m" THEN st.tafPoints/200 ELSE 0 END) as maleFriendReferrals,
SUM(CASE WHEN st.gender = "f" THEN st.tafPoints/200 ELSE 0 END) as femaleFriendReferrals
FROM st) AS subquery