I have developed a query, and in the results for the first three columns I get NULL. How can I replace it with 0?
Select c.rundate,
sum(case when c.runstatus = 'Succeeded' then 1 end) as Succeeded,
sum(case when c.runstatus = 'Failed' then 1 end) as Failed,
sum(case when c.runstatus = 'Cancelled' then 1 end) as Cancelled,
count(*) as Totalrun from
( Select a.name,case when b.run_status=0 Then 'Failed' when b.run_status=1 Then 'Succeeded'
when b.run_status=2 Then 'Retry' Else 'Cancelled' End as Runstatus,
---cast(run_date as datetime)
cast(substring(convert(varchar(8),run_date),1,4)+'/'+substring(convert(varchar(8),run_date),5,2)+'/' +substring(convert(varchar(8),run_date),7,2) as Datetime) as RunDate
from msdb.dbo.sysjobs as a(nolock) inner join msdb.dbo.sysjobhistory as b(nolock)
on a.job_id=b.job_id
where a.name='AI'
and b.step_id=0) as c
group by
c.rundate
When you want to replace a possibly null column with something else, use IsNull.
SELECT ISNULL(myColumn, 0 ) FROM myTable
This will put a 0 in myColumn if it is null in the first place.
You can use both of these methods but there are differences:
SELECT ISNULL(col1, 0 ) FROM table1
SELECT COALESCE(col1, 0 ) FROM table1
Comparing COALESCE() and ISNULL():
The ISNULL function and the COALESCE expression have a similar
purpose but can behave differently.
Because ISNULL is a function, it is evaluated only once. As
described above, the input values for the COALESCE expression can be
evaluated multiple times.
Data type determination of the resulting expression is different.
ISNULL uses the data type of the first parameter, COALESCE follows
the CASE expression rules and returns the data type of value with
the highest precedence.
The NULLability of the result expression is different for ISNULL and
COALESCE. The ISNULL return value is always considered NOT NULLable
(assuming the return value is a non-nullable one) whereas COALESCE
with non-null parameters is considered to be NULL. So the
expressions ISNULL(NULL, 1) and COALESCE(NULL, 1) although
equivalent have different nullability values. This makes a
difference if you are using these expressions in computed columns,
creating key constraints or making the return value of a scalar UDF
deterministic so that it can be indexed as shown in the following
example.
-- This statement fails because the PRIMARY KEY cannot accept NULL values
-- and the nullability of the COALESCE expression for col2
-- evaluates to NULL.
CREATE TABLE #Demo
(
col1 integer NULL,
col2 AS COALESCE(col1, 0) PRIMARY KEY,
col3 AS ISNULL(col1, 0)
);
-- This statement succeeds because the nullability of the
-- ISNULL function evaluates AS NOT NULL.
CREATE TABLE #Demo
(
col1 integer NULL,
col2 AS COALESCE(col1, 0),
col3 AS ISNULL(col1, 0) PRIMARY KEY
);
Validations for ISNULL and COALESCE are also different. For example,
a NULL value for ISNULL is converted to int whereas for COALESCE,
you must provide a data type.
ISNULL takes only 2 parameters whereas COALESCE takes a variable
number of parameters.
if you need to know more here is the full document from msdn.
With coalesce:
coalesce(column_name,0)
Although, where summing when condition then 1, you could just as easily change sum to count - eg:
count(case when c.runstatus = 'Succeeded' then 1 end) as Succeeded,
(Count(null) returns 0, while sum(null) returns null.)
When you say the first three columns, do you mean your SUM columns? If so, add ELSE 0 to your CASE statements. The SUM of a NULL value is NULL.
sum(case when c.runstatus = 'Succeeded' then 1 else 0 end) as Succeeded,
sum(case when c.runstatus = 'Failed' then 1 else 0 end) as Failed,
sum(case when c.runstatus = 'Cancelled' then 1 else 0 end) as Cancelled,
SQL Fiddle Demo
A Simple way is
UPDATE tbl_name SET fild_name = value WHERE fild_name IS NULL
If you are using Presto, AWS Athena etc, there is no ISNULL() function. Instead, use:
SELECT COALESCE(myColumn, 0 ) FROM myTable
Wrap your column in this code.
ISNULL(Yourcolumn, 0)
Maybe check why you are getting nulls
Use COALESCE, which returns the first not-null value e.g.
SELECT COALESCE(sum(case when c.runstatus = 'Succeeded' then 1 end), 0) as Succeeded
Will set Succeeded as 0 if it is returned as NULL.
Add an else to your case statements so that they default to zero if the test condition is not found. At the moment if the test condition isn't found NULL is being passed to the SUM() function.
Select c.rundate,
sum(case when c.runstatus = 'Succeeded' then 1 else 0 end) as Succeeded,
sum(case when c.runstatus = 'Failed' then 1 else 0 end) as Failed,
sum(case when c.runstatus = 'Cancelled' then 1 else 0 end) as Cancelled,
count(*) as Totalrun from
( Select a.name,case when b.run_status=0 Then 'Failed' when b.run_status=1 Then 'Succeeded'
when b.run_status=2 Then 'Retry' Else 'Cancelled' End as Runstatus,
---cast(run_date as datetime)
cast(substring(convert(varchar(8),run_date),1,4)+'/'+substring(convert(varchar(8),run_date),5,2)+'/' +substring(convert(varchar(8),run_date),7,2) as Datetime) as RunDate
from msdb.dbo.sysjobs as a(nolock) inner join msdb.dbo.sysjobhistory as b(nolock)
on a.job_id=b.job_id
where a.name='AI'
and b.step_id=0) as c
group by
c.rundate
sum(case when c.runstatus = 'Succeeded' then 1 else 0 end) as Succeeded,
sum(case when c.runstatus = 'Failed' then 1 else 0 end) as Failed,
sum(case when c.runstatus = 'Cancelled' then 1 else 0 end) as Cancelled,
the issue here is that without the else statement, you are bound to receive a Null when the run status isn't the stated status in the column description. Adding anything to Null will result in Null, and that is the issue with this query.
Good Luck!
by following previous answers I was losing my column name in SQL server db however following this syntax helped me to retain the ColumnName as well
ISNULL(MyColumnName, 0) MyColumnName
For regular SQL, ISNULL(item) can only take one parameter, and thus 90% of these solutions don't work.
I repurposed #Krishna Chavali's answer to make this:
(CASE WHEN (NOT ISNULL(column_name)) THEN column_name ELSE 0 END) AS ColumnName
This will return the value in column_name if it is not null, and 0 if it is null.
UPDATE TableName SET ColumnName= ISNULL(ColumnName, 0 ) WHERE Id = 10
While using case when in where clause in sql query it's not working.
Problem :
I have two tables named TblEmployee and TblAssociate.Both tables contains common columns PeriodId, EmpId and AssociateId. My requirement is to fetch values from
TblEmployee with combination of EmpId and AssociateId from TblAssociate should be excluded.And the exclusion should be based on PeriodId condition.`
If(#PeriodID<50)
BEGIN
SELECT *
FROM TblEmployee
WHERE (EmpId+AssociateId) NOT IN (SELECT EmpId+AssociateId FROM TblAssociate)
END
ELSE
BEGIN
SELECT *
FROM TblEmployee
WHERE (EmpId) NOT IN (SELECT EmpId FROM TblAssociate)
END
The above code is working, but I need to avoid that IF-ELSE condition and I wish to use 'case when' in where clause.Please help
Try this:
SELECT *
FROM TblEmployee
WHERE (EmpId + CASE WHEN #PeriodID<50 THEN AssociateId ELSE 0 END) NOT IN
(SELECT EmpId + CASE WHEN #PeriodID<50 THEN AssociateId ELSE 0 END FROM TblAssociate)
You say your code is working but this is rather odd, since it doesn't make much sense to add together id values. In any case, the above statement produces a result that is equivalent to the code originally posted.
You could use AND-OR combination in the WHERE clause. Additionally, you should not be using + as it may lead to incorrect result. You can rewrite your query as:
SELECT e.*
FROM TblEmployee e
WHERE
(
#PeriodID < 50
AND NOT EXISTS(
SELECT 1
FROM TblAssociate a
WHERE
a.EmpId = e.EmpId
AND a.AssociateId = e.AssociateId
)
)
OR
(
#PeriodID >= 50
AND NOT EXISTS(
SELECT 1
FROM TblAssociate a
WHERE a.EmpId = e.EmpId
)
)
The addition of IDs do not guarantee uniqueness. For instance, if EmpId is 5 and AssociateId is 6, then EmpId + AssociateId = 11, while EmpId + AssociateId = 11 even if EmpId is 6 and AssociateId is 5. In the query below, I made sure that the subquery will stop searching when the first record is found and will return a single record, having the value of 1. We select the employee if and only if 1 is among the results. In the subquery we check the operand we are sure of first and then check if we are not in a period where AssociateId must be checked, or it matches.
select *
from TblEmployee
where 1 in (select top 1 1
from TblAssociate
where TblEmployee.EmpId = TblAssociate.EmpId and
(#PeriodID >= 50 or TblEmployee.AssociateId = TblAssociate.AssociateId))
What could be wrong with this query:
SELECT
SUM(CASE
WHEN (SELECT TOP 1 ISNULL(StartDate,'01-01-1900')
FROM TestingTable
ORDER BY StartDate Asc) <> '01-01-1900' THEN 1 ELSE 0 END) AS Testingvalue.
The get the error:
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
As koppinjo stated what your current (broken) query is doing is checking if you have a NULL-value (or StartDate = '01-01-1900') in your table, return either a 1 or a 0 depending on which, and then attempting to SUM that single value.
There are 2 different logical things you want.
Either getting the amount of rows that has a StartDate or checking if any row is missing StartDate.
SELECT --Checking if there is a NULL-value in table
(
CASE WHEN
(SELECT TOP 1 ISNULL(StartDate,'01-01-1900')
FROM TestingTable
ORDER BY StartDate Asc) <> '01-01-1900' THEN 1
ELSE 0
END
) AS TestingValue
SELECT SUM(TestingValue) TestingValue --Give the count of how many non-NULLs there is
FROM
(
SELECT
CASE WHEN
ISNULL(StartDate,'01-01-1900') <> '01-01-1900' THEN 1
ELSE 0
END AS TestingValue
FROM TestingTable
) T
Here is a SQL Fiddle showing both outputs side by side.
Hard to say, but you probably want something like this:
SELECT
SUM(TestingValue)
FROM
(SELECT
CASE
WHEN ISNULL(StartDate,'01-01-1900') <> '01-01-1900'
THEN 1
ELSE 0
END AS TestingValue
FROM TestingTable) t
As your original query is written now, your subquery will return 1 value overall, so your sum would be 1 or 0 always, not to mention it is illegal. To get around that, this SQL will apply the case statement to every row in the TestingTable and insert the result into a derived table (t), then the 'outer' select will sum the results. Hope this helps!
I have the following table:
Items:
ID Type StockExists
01 Cellphone T
02 Cellphone F
03 Apparrel T
I want to count the number of items with existing stocks, i.e., the number of rows with StockExists='T'. I was performing the query as;
Select count(StockExists)
From [Items] where StockExists='T'
but it is always returning 1. What is the right way to do it?
Edit:
Also, how to perform another such Count operation and add them together in one row, for example,
Select count(StockExists)
From [Items] where StockExists='T'` and `Select count(Type)
From [Items] where Type='Cellphone'` ?
SELECT
COUNT(*) As ExistCount
FROM
dbo.Items
WHERE
StockExists='T'
So your query should work.
Result:
EXISTCOUNT
2
Demo
Update
How to perform another such Count operation and add them together in
one row, for example, Select count(StockExists) From [Items] where
StockExists='T' and Select count(Type) From [Items] where
Type='Cellphone' ?
You can use SUM with CASE:
SELECT
ExistCount = SUM(CASE WHEN StockExists='T' THEN 1 ELSE 0 END) ,
CellphoneCount = SUM(CASE WHEN Type='Cellphone' THEN 1 ELSE 0 END)
FROM
dbo.Items
Result:
EXISTCOUNT CELLPHONECOUNT
2 2
Demo
Select Sum(Case when field = 'this' then 1 else 0 end) as Total
from YourTable
When using CASE WHEN better to use NULL than 0 in ELSE case like below
SELECT
ExistCount = SUM(CASE WHEN StockExists='T' THEN 1 ELSE NULL END) ,
TotalCount = COUNT(ID)
FROM
dbo.Items
Doing a Sum() on a column adds up the values in that column based on group by. But lets say I want to sum these values only if all the values are not null or not 0, then I need a clause which checks if any of the values is 0 before it does the sum. How can I implement such a clause?
I'm using sql server 2005.
Thanks,
Barry
Let's supose your table schema is:
myTable( id, colA, value)
Then, one approach is:
Select colA, sum(value)
from myTable
group by colA
having count( id ) = count( nullif( value, 0 ))
Notice that nullif is a MSSQL server function. YOu should adapt code to your rdbms brand.
Explanation:
count aggregate function only count not null values. Here a counting null values test.
You say that 0+2+3=0 for this case. Assuming that NULL+2+3 should also be zero:
SELECT GroupField,
SUM(Value) * MIN(CASE WHEN COALESCE(Value, 0) = 0 THEN 0 ELSE 1 END)
FROM SumNonZero
GROUP BY GroupField
The above statement gives this result
GroupField (No column name)
case1 5
case2 0
case3 0
with this test data
CREATE TABLE SumNonZero (
GroupField CHAR(5) NOT NULL,
Value INT
)
INSERT INTO SumNonZero(GroupField, Value)
SELECT 'case1', 2
UNION ALL SELECT 'case1', 3
UNION ALL SELECT 'case2', 0
UNION ALL SELECT 'case2', 2
UNION ALL SELECT 'case2', 3
UNION ALL SELECT 'case3', NULL
UNION ALL SELECT 'case3', 3
UNION ALL SELECT 'case3', 4
It makes no sense to eliminate 0 from a SUM because it wont impact the sum.
But you may want to SUM based on another field:
select FIELD, sum(
case when(OTHER_FIELD>0) then FIELD
else 0
end)
from TABLE
group by TABLE