embedding null if within other null if statements - sql

The query below is part of a larger query, but once I add it in, i get a division by 0 error.
(SUM(likes + comments + video_views) / nullif(SUM(influencer_starting_followers),
0))/ (SUM(average_likes + average_comments + average_views) /nullif(SUM(followers_count),
0)) AS Achieved,
I'm quite new to sql and i'm not entirely sure how to go about changing this section (primarily the denominator as shown below) so that Achieved is only calculated if the query below is not= 0 or null
(SUM(average_likes + average_comments + average_views) /nullif(SUM(followers_count)

Your second division is not "nullif protected"
(SUM(likes + comments + video_views) / nullif(SUM(influencer_starting_followers),
0))/ nullif(SUM(average_likes + average_comments + average_views),0) /nullif(SUM(followers_count),
0)) AS Achieved,
nullif returns Null if the 2 parameters are equal, that's to avoid to divide by zero.

Related

Teradata Arithmetic operations

In Teradata when computing a percentage (see example below), I get 0 as an answer because Terada rounds results based on the number of decimal places the number have. to my knowledge I have found 2 possible solution to avoid the zero value return.
1- define the decimal number in table with a larger scale value. e.g decimal(18,4) instead of decimal(18,2)
2- cast the first arithmetic operation that occurs to a decimal number with a larger scale value. e.g. select (cast(2.0 as decimal(10,6)) / 10.0) * 100;
has anyone encounter this problem before and what is the solution you went with to solve the problem? thank you in advance.
these are the actual values and the correct answer should be 0.25
select ((28.97 + 28.97) / (11586.87 + 11586.87)) * 100
,(cast((28.97 + 28.97) as decimal(20,4)) / (11586.87 + 11586.87)) * 100
,((cast(28.97 as decimal(18,4)) + 28.97) / (11586.87 + 11586.87))
,(100 * (28.97 + 28.97) / (11586.87 + 11586.87))
,(28.97 + 28.97) , (11586.87 + 11586.87);

Does the SQL CASE statement treat variables differently from columns?

I have the following code in a stored procedure and am trying to conditionally format a calculated number based on its length (if the number is less than 4 digits, pad with leading zeros). However, my case statement is not working. The "formattedNumber2" result is the one I'm looking for.
I'm assuming the case statement treats the variable strangely, but I also don't know of a way around this.
DECLARE #Number int = 5
SELECT
CASE
WHEN (LEN(CONVERT(VARCHAR, #Number)) > 4)
THEN #Number
ELSE RIGHT('0000' + CAST(#Number AS VARCHAR(4)), 4)
END AS formattedNumber,
LEN(CONVERT(VARCHAR, #Number)) AS numberLength,
RIGHT('0000' + CAST(#Number AS VARCHAR(4)), 4) AS formattedNumber2
I get the following results when I run the query:
formattedNumber numberLength formattedNumber2
-------------------------------------------------
5 1 0005
SQL DEMO
The problem is you are using different data type on your case , integer and string. So the CASE stay with the first type he find and convert the rest.
CASE WHEN (LEN(convert(VARCHAR, #Number)) > 4) THEN convert(VARCHAR, #Number)
This can be done a lot easier with format() since version 2012.
format(n,
'0000')
And that would also handle negative values, which your current approach apparently doesn't.
Prior 2012 it can be handled with basically replicate() and + (string concatenation).
isnull(replicate('-',
-sign(n)), '')
+
isnull(replicate('0',
4
-
len(cast(abs(n) AS varchar(10)))
),
'')
+
cast(abs(n) AS varchar(10))
(It targets integer values, choose a larger length for the varchar casts for bigint.)
db<>fiddle

prevent divide by zero when both values are obtained from a calculation

I'm trying to complete the following:
(value_a + value_b)/(value_c + value_d)
Usually I have avoided a divide by zero error with something like this:
CASE WHEN value_a + value_b = 0
THEN 0
ELSE (value_a + value_b)/(value_c + value_d)
END
For some reason in this isn't working, which makes me wonder if in the past one of my result sets have never included zero's.
Any pointers on this would be gratefully received.
You're checking the numerator, not the denominator:
CASE WHEN value_c + value_d = 0
THEN 0
ELSE (value_a + value_b)/(value_c + value_d)
END
Anothere way is to use NULLIF and COALESCE:
COALESCE((value_a + value_b)/NULLIF((value_c + value_d),0)
,0)

Avoiding duplicating sql Switch conditions

(needs to be compliant code down to Access 2003)
Apologies if this is a "doh!" moment (still learning)...as part of a SELECT statement I have the following field called Total whose purpose, for each record, is to calculate the total of 4 previous fields. A '0' value is passed to Total if the sum is <1000, if it isn't then the actual sum is passed.
Summarised we have:
,IIf(
Switch(……) +
Switch(……) +
Switch(……) +
Switch(……)<1000,0,
Switch(……) +
Switch(……) +
Switch(……) +
Switch(……))
AS Total
In its much expanded version it does work, however, this looks cumbersome since it means having to repeat the initial 4 Switch conditions twice (once if <1000 and once if not).
Is there any way to reduce this?
One method is to use a subquery:
select iif(val < 1000, 0, val)
from (select x.*, (switch() + . . . + switch()) as val
from x
) as x1;

Get average of fields

In this SQL statement:
select (ISNULL(Tbl1.Bromod,0) + ISNULL(Tbl1.Bromoform,0) +
ISNULL(Tbl1.Chlor,0) + ISNULL(Tbl1.Dibromoc,0)) / 4 )
from TblTruck
I'd like to dynamically change the value that is 4 currently to be the number of values that are NOT NULL.
What I am trying to do is to get the average ignoring NULL entries.
Say if Bromod is NULL and the others are not BULL, I would then divide by 3, as 3 actually have values.
select (
ISNULL(Tbl1.Bromod,0) + ISNULL(Tbl1.Bromoform,0) + ISNULL(Tbl1.Chlor,0) + ISNULL(Tbl1.Dibromoc,0)
)
/ ISNULL(
NULLIF(
CONVERT(INT,CONVERT(BIT,ISNULL(Tbl1.Bromod,0))) + CONVERT(INT,CONVERT(BIT,ISNULL(Tbl1.Bromoform,0))) + CONVERT(INT,CONVERT(BIT,ISNULL(Tbl1.Chlor,0))) + CONVERT(INT,CONVERT(BIT,ISNULL(Tbl1.Dibromoc,0)))
,0
)
,1
)
from TblTruck Tbl1
So,neat trick, all #s other than zero convert as a true when cast as a bit. So, NULLs and 0's become zero and all other values become 1. Sum together and that gives you what you are looking for. This solution also handles a divide by zero issue that would arise if all values were null/zero.