SQL adding numbers while handling nulls - sql

I have this statement here:
SELECT sum(table1.foo + table1.bar) AS Sum
FROM table1
GROUP BY Fname;
When I try to add the numbers from foo and bar if one value from foo or bar is null it throws the numbers and gives me a different count sum
foo | bar
6 4
5 null
9 1
2 1
3 null
I want it to add all the numbers giving me a total of 31
but in this case it gives me a total of 23
Would love some help! Thanks!

Use coalesce():
SELECT sum(coalesce(table1.foo, 0) + coalesce(table1.bar, 0)) AS Sum
FROM table1
GROUP BY Fname;
If you want the total, total on one row, remove the group by:
SELECT sum(coalesce(table1.foo, 0) + coalesce(table1.bar, 0)) AS Sum
FROM table1;

Any Number + NULL = NULL. You want to indicate to the engine that when it sees a NULL, it should treat that NULL value as 0.
SELECT sum(ISNULL(table1.foo, 0) + ISNULL(table1.bar,0)) AS Sum
FROM table1
GROUP BY Fname;

I believe you'll need to have SQL replace nulls with a zero using "ISNULL".
Try:
SELECT sum(ISNULL(fix_bat_sum.foo, 0) + ISNULL(fix_bat_sum.bar, 0) ) AS Sum

Related

How to sum non-null values from multiple columns (workaround for CASE WHEN limitation) Postgresql

So I essentially want to work around the fact that CASE WHEN stops executing when it finds its first TRUE return.
I'd like to sum every instance of a non-null value between multiple columns, and group these based on my ID. Example table:
id
input1
input2
input3
1
a
null
k
2
null
null
b
3
null
null
null
4
q
null
r
5
x
p
j
6
null
y
q
I would like the output of my function to be:
id
total_inputs
1
2
2
1
3
0
4
2
5
3
6
2
Any work arounds? Is a custom function in order to create a count of unique or non-null entries across multiple columns, grouped by row?
I know I can create a CTE and assign 1's to each non-null column but that seems tedious (my data set has 39 inputs) - and I'd like to have a reusable function I could use again in the future.
You could use a simple aggregation as the following:
Select id,
Count(input1) + Count(input2) + Count(input3) As total_inputs
From table_name
Group By id
Order By id
Noting that Count(inputX) = 0, where inputX is null.
See a demo.
We can simply use:
select ID,
case when input1 is not null then 1 else 0 end
+ case when input2 is not null then 1 else 0 end
+ ...
+ case when input39 is not null then 1 else 0 end as total_inputs
from ...
No need to group by if you want every row (or count, we are not aggregating rows - that is what COUNT()..GROUP BY is for), or CTE.
Also, for some PostgreSQL versions, there is a num_nulls function to count null parameters:
select
, 32-num_nulls(input1, input2, input3, ..., input32)

Why Sum in database query giving NULL

Suppose I have a table named "Expense" and it has some month-wise expense which may contain some "NULL", now I want to check the yearly expenses in total with this below query:-
Select Sum(January) + Sum (February) ..... (I skipped the rest 10 months)
from Expense
This gives result as "NULL"
How can I avoid this situation? I think there are more convenient way to check the yearly sum
All arithmetic or logical operations involving NULL yield NULL. For example:
SELECT 1 + NULL -- NULL
You must convert NULL to zeros before you can + them:
SELECT
COALESCE(SUM(January), 0) +
COALESCE(SUM(February) , 0) +
...
It is also possible to add the columns first and then calculate the sum:
SELECT SUM(
COALESCE(January, 0) +
COALESCE(February, 0) +
)
Be advised that (i) SUM skips NULL values (ii) returns NULL instead of 0 if all values are NULL:
SELECT SUM(a) FROM (VALUES
(1),
(2),
(NULL)
) AS v(a) -- returns 3 instead of NULL
It will return NULL if all values encountered were NULL:
SELECT SUM(a) FROM (VALUES
(CAST(NULL AS INT)),
(NULL),
(NULL)
) AS v(a) -- returns NULL instead of 0
use coalesce function to convert null to 0 then use sum
Select Sum(coalesce(January,0)) + Sum (coalesce(February,0)) ..... (I skipped the rest 10 months)
from Expense
Just use coalesce [ with 0 as the second argument ] to replace nulls for all month columns, otherwise you can not get true results from aggregation of numeric values :
select sum(coalesce(January,0)+coalesce(February,0) ... )
from Expense
That because you have NULL values, you can use Case, Coalesce or IIF:
Select SUM(IIF(Col IS NULL, 0, Col))
Select SUM(CASE WHEN Col IS NULL THEN 0 ELSE Col END)
Select COALESCE(Sum(Col), 0)
Any arithmetic function will return null if there is at least one null value in the given column. That's why you should use functions like coalesce or isNull (MSSQL), NVL (Oracle).
You can use ISNULL(SUM(January),0).
Because null + value is always null and in your sample some months sums are null, you can avoid this by adding ISNULL
Select isnull(Sum(January),0) +
isnull(Sum(February),0)
--..... (I skipped the rest 10 months)
from Expense
Alternatively you can use below way:
Select Sum(
isnull(January,0) +
isnull(February,0)
)
--..... (I skipped the rest 10 months)
from Expense

Count every rows

i tried to count the value of every rows in MYSQL. But it only count the first row only. Can someone assist
First Query:
SELECT A, B, C
FROM [TEST].[dbo].[TEST3]
Result:
A B C
7 8 9
1 2 NULL
1 3 4
1 NULL 1
Count every rows but only the first row appear as result.
Query
SELECT COUNT (A + B + C)
FROM [TEST].[dbo].[TEST3]
Result:
2
It supposed to be 7+8+9 = 22
1+2+NULL = 3
etc.
Just take the sum of the columns directly:
SELECT A, B, C,
COALESCE(A, 0) + COALESCE(B, 0) COALESCE(C, 0) AS total
FROM [TEST].[dbo].[TEST3]
The reason why your current query using COUNT returns a single row is that COUNT is an aggregate function. In the absence of GROUP BY, you are telling SQL Server to return a count over the entire table.
This is what you want:
SELECT IFNULL(A,0)+IFNULL(B,0)+IFNULL(C,0)
FROM [TEST].[dbo].[TEST3]
You do not want to use COUNT() here. COUNT() is an aggregate function. It output once per group. In your case, the whole query will output only one value.
Moreover, adding NULL to anything will be NULL and COUNT() will ignore that. Therefore the output of your query is 2.
COUNT() is a aggregate function which will return group result.
The result is actually correct since 1 + 2 + NULL = NULL, not 3.
SELECT COUNT (A + B + C) FROM [TEST].[dbo].[TEST3]
Returns 2 because COUNT() will count only non-null value. If you run the query without COUNT() it will return 4 rows.
SELECT A + B + C FROM [TEST].[dbo].[TEST3]
The result is
24
NULL
8
NULL
However, if you wanted to return rows considering NULL as 0, you can use COALESCE within the columns,
SELECT COALESCE(A, 0) + COALESCE(B, 0) + COALESCE(C, 0)
FROM [TEST].[dbo].[TEST3]
will now return
24
3
8
2
And when you write it with count, it will now return 4.
SELECT COUNT(COALESCE(A, 0) + COALESCE(B, 0) + COALESCE(C, 0) )
FROM [TEST].[dbo].[TEST3]
Result:
4
Here's a Demo.
SELECT
A, B, C,
Total = A + B+ C
FROM dbo.TEST
DO NOT USE COUNT.

Is it possible to force reutrn value from query when no rows found? [duplicate]

This question already has answers here:
Return a value if no record is found
(6 answers)
Get 0 value from a count with no rows
(6 answers)
Closed 7 years ago.
I have a simple query:
Select qty from X where id=....;
this query always return 0 or 1 row.
when it return 1 row everything works.
but if it return 0 rows my query fails as qty is used in calculations. (This is acatually a Sub query in Select statment).
I need somehow to make sure the query always return 1 row.
I tried:
Select coalesce(qty,0) from X where id=....;
but it doesn't help as if there are no rows the coalesce is useless.
if no row found it should give 0
How can I fix it?
You can do this:
SELECT COALESCE( (SELECT qty from X where id=....), 0)
if nothing is returned from the inner SELECT statement, COALESCE will give you 0 in the outer SELECT statement.
Select *.a from (
Select qty, 0 as priority from X where id=....
Union
Select 0, 1 as priority
) a
Order By a.priority Asc
Limit 1
This select basically ensures that at least one row is returned by adding an additional row to the end and by adding the limit statement we just return the first row.
So now there is the case where at least one row is found and the additional row is added to the end. In this case the first row found (see ->) will be returned due to the ascending order by priority:
qty priority
-> 1 0
3 0
4 0
. .
0 1
And then there is the case where no row is found but the additional row is returned:
qty priority
-> 0 1
try this.
SELECT COALESCE((SELECT qty
FROM x
WHERE id = #MyIdVar), 1)
If no records found then its return 'No rows found'
if not exists(Select * from table where condition=...)
Begin
Select * from table where condition=...
End
Else
Begin
Select 'No rows found'
End
Whenever you use this you will get record else no record found message.
Without using COALESCE()
select qty from X where id=1 UNION SELECT 0 order by qty desc limit 1
Demo

T-SQL select sum of Two integer column

I have two columns Val1 and Val2 as int in SQL Server 2008
When I select Tot = Val1+Val2 from Table, I get null as Tot
How do I get total of two int columns selected?
Many thanks.
It's likely that you have a null value in one of the columns. that will produce a null-valued result.
You can do the following, if you want null to represent 0.
SELECT Tot = ISNULL(Val1, 0) + ISNULL(Val2, 0)
FROM Table
Use select Tot = isnull(Val1, 0) + isnull(Val2, 0) from Table