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
I would like to have a condition statement before Order By.
In my below query there is chance for Marks to be null, in that case I would like to Order by Rank Asc
SELECT TOP 1 P.[Score]
FROM dbo.[Profile] P
WHERE P.[ProfileId] = #ProfileId
ORDER BY P.[Marks] DESC AS [ProfileScore]
I tried changing it to the below way but it’s giving a compile error
SELECT TOP 1 P.[Score]
FROM dbo.[Profile] P
WHERE P.[ProfileId] = #ProfileId
ORDER BY
(CASE WHEN P.[Marks] IS NOT NULL THEN P.[Marks] END) DESC,
(CASE WHEN P.[Marks] IS NULL THEN P.[Rank] END) ASC AS [ProfileScore]
But it gives an error:
Incorrect syntax near the keyword 'DESC'
There is an AS [ProfileScore] too many in your ORDER BY. You cannot create aliases in ORDER BY.
If both Marks and Rank are numeric, I suggest:
SELECT TOP 1 P.[Score]
FROM dbo.[Profile] P
WHERE P.[ProfileId] = #ProfileId
ORDER BY CASE WHEN P.[Marks] IS NULL THEN P.[Rank] ELSE -P.[Marks] END;
This is my query:
SELECT patientname, patientID,
(CASE WHEN patientID is not null THEN 'yes'
WHEN CpatientID is null then 'No'
END) as submittedintohospital
FROM dbo].[database](nolock)
and patientname = "John Smith"
this is data result:
PatientName PatientID
John Smith 12345488999 NULL
John Smith 12880889976 NULL
As you can see, a patient have 2 rows of result, and I want to set a condition where only ALL the rows
's patientID is null, then it will go into case for yes.
Because currently query I wrote it will show patient data with both null and non-null value:
For example:
John Wick 1895
John Wick NULL
I want to eliminate that and only pull patient name where all the rows must have null patientID, not just one row.
I want to set a condition where only ALL the rows 's patientID is null, then it will go into case for yes.
You can use window functions:
select patientname, patientid,
case when max(patientid) over(partition by patientname) is null
then 'yes'
else 'no'
end as submittedintohospital
from [dbo].[database]
If you want to actually filter the results:
select patientname, patientid
from (
select d.*,
max(patientid) over(partition by patientname) max_patientid
from [dbo].[database] d
) d
where max_patientid is null
not exists might also come handy for filtering:
select d.*
from [dbo].[database] d
where not exists (
select 1
from [dbo].[database] d1
where d1.patientname = d.patientname and d1.patientid is not null
)
I was wondering if it is possible to retrieve the net changes similar to cdc.fn_cdc_get_net_changes_<capture_instance>(from_lsn , to_lsn, 'all with mask') of tables that don't have a primary key but do have a constraint that ensures that one (or more) column(s) is unique.
It took me a while but I think I have a solution that works, let me know if there's a better solution or if you see a bug in mine.
Let's assume a capture instance named capture_instance of a table with unique column ID and non-unique columns field1, field2 and field3 and variables #from_lsn and #to_lsn.
WITH
cdc_all AS (
-- Retrieve the change table with all changes
SELECT *
FROM cdc.fn_cdc_get_all_changes_capture_instance(#from_lsn, #to_lsn, 'all')
),
f AS (
SELECT cdc_all.*, ops.[delete], ops.[insert], ops.[update], ops.[net_op]
FROM cdc_all
INNER JOIN (
-- Retrieve three flags for insert, update and delete and the net operation
-- also filter insert + delete pairs because it results in no change
SELECT *
FROM (
SELECT ID
, MAX(CASE WHEN __$operation = 1 THEN 1 ELSE 0 END) as [delete]
, MAX(CASE WHEN __$operation = 2 THEN 1 ELSE 0 END) as [insert]
, MAX(CASE WHEN __$operation = 4 THEN 1 ELSE 0 END) as [update]
, MIN(__$operation) [net_op]
FROM cdc_all
GROUP BY ID
) ops
WHERE NOT (ops.[delete] = 1 AND ops.[insert] = 1)
) ops ON cdc_all.ID = ops.ID
)
SELECT net.[max_lsn], f.[net_op] __$operation
, (CASE WHEN net.__$update_mask != 0x0 THEN net.__$update_mask ELSE NULL END) __$update_mask
, f.[ID], [field1], [field2], [field3]
FROM f
INNER JOIN (
-- bitwise OR the __$update_mask of the updates
-- also retrieve the last lsn of each row which should be used as the __$start_lsn of the result set
SELECT ID
, CAST(SUM(DISTINCT CAST((CASE WHEN f.[__$operation] = 4 AND f.[insert] != 1 THEN f.[__$update_mask] ELSE 0 END) as int)) as varbinary(2)) [__$update_mask]
, MAX(__$start_lsn) [max_lsn]
FROM f
GROUP BY ID
) net ON f.ID = net.ID AND f.__$start_lsn = net.[max_lsn]
To match the behavior of cdc.fn_cdc_get_net_changes_ exactly the size of the varbinary at the end should be as small as possible for all fields to fit, but a larger value wouldn't break the functionality.
Basically I want COUNT a CASE when values are present in 2 columns.
For example:
SELECT
COUNT
(CASE WHEN 1.sample AND 2.sample IN ('a','b','c')
THEN 1
ELSE NULL
END
) AS CASE
FROM table1 AS 1
INNER JOIN table2 AS 2
...
Message:
Conversion failed when converting the varchar value '08:12.06' to data
type int. Warning: Null value is eliminated by an aggregate or other
SET operation.
I get what's triggering the error, I just don't know a solution to count the case when values are present in both columns.
Can you try this and see if it works? I think this is what you are looking for.
SELECT
SUM
(CASE WHEN 1.sample IN ('a','b','c') AND 2.sample IN ('a','b','c')
THEN 1
ELSE 0
END
) AS CASE
FROM table1 AS 1
INNER JOIN table2 AS 2
You need to list the columns separately for comparison. Usually I specify a column to count, and you do not need to put NULL for the else condition.
SELECT
COUNT
(CASE WHEN 1.sample IS NULL OR 2.sample IS NULL THEN 0
WHEN ( 1.sample IN ('a','b','c')
AND 2.sample IN ('a','b','c')
)
THEN 1.sample
END
) AS CASE
FROM table1 AS 1
INNER JOIN table2 AS 2 ON....