SQL: sum 3 columns when one column has a null value? - sql

SELECT
sum(TotalHoursM)
+ (TotalHoursT)
+ (TotalHoursW)
+ (TotalHoursTH)
+ (TotalHoursF)
AS TOTAL
FROM LeaveRequest

If the column has a 0 value, you are fine, my guess is that you have a problem with a Null value, in that case you would need to use IsNull(Column, 0) to ensure it is always 0 at minimum.

The previous answers using the ISNULL function are correct only for MS Sql Server. The COALESCE function will also work in SQL Server. But will also work in standard SQL database systems. In the given example:
SELECT sum(COALESCE(TotalHoursM,0))
+ COALESCE(TotalHoursT,0)
+ COALESCE(TotalHoursW,0)
+ COALESCE(TotalHoursTH,0)
+ COALESCE(TotalHoursF,0) AS TOTAL FROM LeaveRequest
This is identical to the ISNULL solution with the only difference being the name of the function. Both work in SQL Server but, COALESCE is ANSI standard and ISNULL is not. Also, COALESCE is more flexible.
ISNULL will only work with two parameters. If the first parameter is NULL then the value of the second parameter is returned, else the value of the first is returned.
COALESCE will take 2 to 'n' (I don't know the limit of 'n') parameters and return the value of the first parameter that is not NULL. When there are only two parameters the effect is the same as ISNULL.

SELECT sum(isnull(TotalHoursM,0))
+ isnull(TotalHoursT,0)
+ isnull(TotalHoursW,0)
+ isnull(TotalHoursTH,0)
+ isnull(TotalHoursF,0))
AS TOTAL FROM LeaveRequest

Just for reference, the equivalent statement for MySQL is: IFNull(Column,0).
This statement evaluates as the column value if not null, otherwise it is evaluated as 0.

You can use ISNULL:
ISNULL(field, VALUEINCASEOFNULL)

looks like you want to SUM all the columns (I'm not sure where "sum 3 columns" comes from), not just TotalHoursM, so try this:
SELECT
SUM( ISNULL(TotalHoursM ,0)
+ ISNULL(TotalHoursT ,0)
+ ISNULL(TotalHoursW ,0)
+ ISNULL(TotalHoursTH ,0)
+ ISNULL(TotalHoursF ,0)
) AS TOTAL
FROM LeaveRequest

You can also use nvl(Column,0)

I would try this:
select sum (case when TotalHousM is null then 0 else TotalHousM end)
+ (case when TotalHousT is null then 0 else TotalHousT end)
+ (case when TotalHousW is null then 0 else TotalHousW end)
+ (case when TotalHousTH is null then 0 else TotalHousTH end)
+ (case when TotalHousF is null then 0 else TotalHousF end)
as Total
From LeaveRequest

If you want to avoid the null value use IsNull(Column, 1)

Related

I need Total return NULL only If all values are NULL

A query like these
SELECT A,B,C,D, (A+B+C+D) as TOTAL
FROM TABLES
If A,B,C and D is NULL. i need to return NULL.
But if any one of the them is not NULL. Other will change from NULL to zero.
And total(a+b+c+d).
Now try this way
SELECT A,B,.. CASE WHEN (A IS NULL) AND (B IS NULL) AND ... THEN NULL
ELSE ISNULL(A,0) + ISNULL(B,NULL) +... END
But it is so long and I have a lot of total in this whole query.
What the best way I can use for this problem?
The semantics you want are the same as those provided by SUM.
SELECT A,B,C,D,
(SELECT SUM(val)
FROM (VALUES(A),
(B),
(C),
(D)) T (val)) AS Total
FROM YourTable
I would use COALESCE function.
Evaluates the arguments in order and returns the current value of the first expression that initially does not evaluate to NULL.
SELECT
CASE WHEN COALESCE(A,B,C,D) IS NOT NULL THEN
COALESCE(A,0 ) + COALESCE(B,0 )+ COALESCE(C,0 ) + COALESCE(D,0 )
END
FROM TABLES
COALESCE() is a function that you can use:
SELECT A,B,..
CASE WHEN COALESCE(A,B,C,D) IS NULL THEN NULL ELSE ISNULL(A,0) + ISNULL(B,0) +... END

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 column with specific condition

How can i count columns that hold particular values - but have it as a grand-total.
table data:
Code No
1 *
2 -
3 4
4
If for example i wanted to count how many rows had * and - and space
I could do
Case when No = '*'
Then COUNT(No)
when No = '-' then count(No)
when No = '' then count(No)
else 0 end as 'Count'
but this returns 4
http://sqlfiddle.com/#!9/f73409/4
I would want this to return 3
Any help would be appreciated
Use IN:
select Sum(Case when No IN ('*', '-', '') then 1 else 0 end) as Count
from Table1
See Fiddle.
Standard SQL has a particular feature for that: the filter clause that follows aggregates.
Unfortunately, it is not very widely supported (mainly PostgreSQL).
There is an easy workaround using case however:
COUNT(CASE WHEN <condition> THEN 1 END)
This works because the implied else null clause of case and because count does not count null.
More about the filter clause and ways to mimic it: http://modern-sql.com/feature/filter

SQL Replacing NULL with 0 in a query

I'm trying to replace a Null value with a 0 and then do a calculation on this field, but not able to make it work. In all 4 of the examples below I'm still getting a Null value.
Any suggestions with how to write this?
Here's what I've tried:
select
ISNULL(posamt, 0) as total1,
coalesce (posamt, 0) as total2,
case when PosAmt = 0 then '0' else CONVERT(varchar(11), isnull(posamt, 0))end as total3,
CONVERT(varchar(11),isnull(posamt,0)) as total4
from mytable
I believe you need to have the ISNULL(posamt,0) in the CASE WHEN statements. It will never be equal to 0 when posamt is NULL.

Sum on multiple columns with nullable values

I have to edit a stored procedure who has to return the sums of three columns having nullable values. If there is a null value, I need to cast it to 0
Here is a screenshot of data :
And here is the originial request using the first column only :
SELECT SUM(reglProj.Montant) /* SUM of 'Montant', 'FraisMagasing', 'FraisVendeur' instead */ AS SommeReglement
FROM Projet.LigneEcheancierProjet ligne
INNER JOIN Projet.ReglementProjetEcheance reglProj ON reglProj.LigneEcheancierProjetId = ligne.LigneEcheancierProjetId
....
Do you have some best practices using the sum and case conditions in T-SQL ?
--ANSI standard
SELECT SUM(COALESCE(col1,0)) + SUM(COALESCE(col2,0)) + SUM(COALESCE(col3,0))
--SQL Server Style
SELECT SUM(ISNULL(col1,0)) + SUM(ISNULL(col2,0)) + SUM(ISNULL(col3,0))
--The one wthout functions. It will work the same as previous OR FASTER.
SELECT SUM(CASE WHEN col1 IS NULL THEN 0 ELSE col1 END) + SUM(CASE WHEN col2 IS NULL THEN 0 ELSE col2 END) + SUM(CASE WHEN col3 IS NULL THEN 0 ELSE col3 END)
Choose one for yourself.
OR you might need following (if you want to add sums by row):
--ANSI standard
SELECT SUM(COALESCE(col1,0) +COALESCE(col2,0) + COALESCE(col3,0))
--SQL Server Style
SELECT SUM(ISNULL(col1,0)+ ISNULL(col2,0) + ISNULL(col3,0))
--The one wthout functions. It will work the same as previous OR FASTER.
SELECT SUM(CASE WHEN col1 IS NULL THEN 0 ELSE col1 END + CASE WHEN col2 IS NULL THEN 0 ELSE col2 END + CASE WHEN col3 IS NULL THEN 0 ELSE col3 END)
In Sql Server, (and probably in most if not all relational databases) the SUM Aggregation function ignores null values by default, so there really is no need to use coalesce or isnull inside it.
If you want the sum of all 3 columns for every single row, then you need to use isnull:
SELECT ISNULL(reglProj.Montant,0) +
ISNULL(reglProj.FraisMagasing ,0) +
ISNULL(reglProj.FraisVendeur,0)
FROM Projet.LigneEcheancierProjet ligne
INNER JOIN Projet.ReglementProjetEcheance reglProj
ON reglProj.LigneEcheancierProjetId = ligne.LigneEcheancierProjetId
If you need the aggregated sum of all 3 columns you can simply do it like this:
SELECT ISNULL(SUM(reglProj.Montant), 0) +
ISNULL(SUM(reglProj.FraisMagasing), 0) +
ISNULL(SUM(reglProj.FraisVendeur), 0)
FROM Projet.LigneEcheancierProjet ligne
INNER JOIN Projet.ReglementProjetEcheance reglProj
ON reglProj.LigneEcheancierProjetId = ligne.LigneEcheancierProjetId
It seems you are looking for ISNULL actually
SELECT SUM( ISNULL(reglProj.Montant,0) + ISNULL(FraisMagasing,0)+ ISNULL(FraisVendeur,0)) AS SommeReglement
FROM Projet.LigneEcheancierProjet ligne
INNER JOIN Projet.ReglementProjetEcheance reglProj ON reglProj.LigneEcheancierProjetId = ligne.LigneEcheancierProjetId