replace NULL with Blank value or Zero in sql server - sql

I have a temp table and in that one of my column total_amount is of integer type and NOT NULL. While querying data, I received NULL values for total_Amount column.
How ever I used following syntax to remove nulls but some how still NULL values appearing, correct me if I am wrong.
Create table #Temp1
(
issue varchar(100) NOT NULL,
total_amount int NOT NULL
)
This is my query
Case when total_amount = 0 then 0
else isnull(total_amount, 0)
end as total_amount
I am facing issue at my else part.

You can use the COALESCE function to automatically return null values as 0. Syntax is as shown below:
SELECT COALESCE(total_amount, 0) from #Temp1

The coalesce() is the best solution when there are multiple columns [and]/[or] values and you want the first one. However, looking at books on-line, the query optimize converts it to a case statement.
MSDN excerpt
The COALESCE expression is a syntactic shortcut for the CASE expression.
That is, the code COALESCE(expression1,...n) is rewritten by the query optimizer as the following CASE expression:
CASE
WHEN (expression1 IS NOT NULL) THEN expression1
WHEN (expression2 IS NOT NULL) THEN expression2
...
ELSE expressionN
END
With that said, why not a simple ISNULL()? Less code = better solution?
Here is a complete code snippet.
-- drop the test table
drop table #temp1
go
-- create test table
create table #temp1
(
issue varchar(100) NOT NULL,
total_amount int NULL
);
go
-- create test data
insert into #temp1 values
('No nulls here', 12),
('I am a null', NULL);
go
-- isnull works fine
select
isnull(total_amount, 0) as total_amount
from #temp1
Last but not least, how are you getting null values into a NOT NULL column?
I had to change the table definition so that I could setup the test case. When I try to alter the table to NOT NULL, it fails since it does a nullability check.
-- this alter fails
alter table #temp1 alter column total_amount int NOT NULL

You should always return the same type on all case condition:
In the first one you have an character and on the else you have an int.
You can use:
Select convert(varchar(11),isnull(totalamount,0))
or if you want with your solution:
Case when total_amount = 0 then '0'
else convert(varchar(11),isnull(total_amount, 0))
end as total_amount

Try This
SELECT Title from #Movies
SELECT CASE WHEN Title = '' THEN 'No Title' ELSE Title END AS Titile from #Movies
OR
SELECT [Id], [CategoryId], ISNULL(nullif(Title,''),'No data') as Title, [Director], [DateReleased] FROM #Movies

Different ways to replace NULL in sql server
Replacing NULL value using:
1. ISNULL() function
2. COALESCE() function
3. CASE Statement
SELECT Name as EmployeeName, ISNULL(Bonus,0) as EmployeeBonus from tblEmployee
SELECT Name as EmployeeName, COALESCE(Bonus, 0) as EmployeeBonus
FROM tblEmployee
SELECT Name as EmployeeName, CASE WHEN Bonus IS NULL THEN 0
ELSE Bonus END as EmployeeBonus
FROM tblEmployee

Replace Null Values as Empty: ISNULL('Value','')
Replace Null Values as 0: ISNULL('Value',0)

Related

How to insert value in SQL table if not exists

I'm new in SQL. I'm trying to insert data into a SQL table. If I insert for the first time it works but if I try to do a new insert I get the error
Violation of UNIQUE KEY constraint.
The unique key constraint is on (uc, start_date). The error occurs because there is already the record (-1, 1900-01-01) in the table. Here is my code:
insert into tableA ([start_date],[end_date],[uc],[desc],[ind_sus])
select '1900-01-01' [start_date]
,'9999-12-31'[end_date]
,case when right([DIM], 1) = '|' then '-1'
else right([DIM], 2)
end [uc]
,'' [desc]
,0 [ind_sus]
from tableB b
where right([DIM], 2) NOT IN (select uc from tableA a
where a.uc = right([DIM], 2)
and convert(date,b.[DATETRIAL]) between a.start_date and a.end_date)
group by case when right([DIM], 1) = '|' then '-1'
else right([DIM], 2)
end
The data that I'm trying to insert fulfills the when condition of the case and therefore another (-1, 1900-01-01) as key. I tried:
case when not exists(select uc from tableA where uc = '-1') then '-1'
to insert only if the data doesn't exist. It didn't work because I have to put the same code in the group by clause and I realized that I cannot do a subquery in the group by clause. So, is there a way to check at the case clause level if a value already exist before inserting? Or should I rewrite the request in another way? Database can't be modified
I need suggestions please.
In order to be able to check and insert data when not exists you need to use MERGE operator (see docs for more info).
Since you did not provide us with test data, I'm not sure I can easily update your query, so here is an example I made up to show you how to do things you need using MERGE.
Create table and insert 1 row with id = 1:
create table some_table(id int primary key, text_col varchar(10));
insert into some_table values(1, 'first');
Try to insert a line with same id
insert into some_table values(1, 'another first'); -- it fails of course
same thing using merge
merge into some_table -- target table
using
(select 1 id, 'another first' text_col) new_data -- source data
on some_table.id = new_data.id -- column to check on
when not matched then
insert (id, text_col) values(new_data.id, new_data.text_col);
I hope this helps
My try to change your query to merge would be like that
(keep in mind I did not tested it so fixing syntax or possible data errors is up to you)
merge into tableA a
using (select uc
,'1900-01-01' [start_date]
,'9999-12-31'[end_date]
,case when right([DIM], 1) = '|' then '-1'
else right([DIM], 2) end [uc]
,'' [desc]
,0 [ind_sus]
from tableB b
group by case when right([DIM], 1) = '|' then '-1'
else right([DIM], 2)
end) b
on a.right([DIM], 2) = b.uc
and convert(date,b.[DATETRIAL]) between a.start_date and a.end_date
when not matched then
insert([start_date],[end_date],[uc],[desc],[ind_sus])
values(b.start_date, b.end_date, b.uc, b.desc, b.ind_sus)

SQL if else filter in single select statement

Is it possible to output the following:
for each group by personId, if email ends with '#company.com' then filter by [where type = 'h'] else filter [where type = 't']
so the query would output the following:
1 bob#hotmail.com h
2 bill#hotmail.com t
create table #emails (personId int, email nvarchar(100), type char(1) )
insert into #emails values (1, 'bob#company.com', 't');
insert into #emails values (1, 'bob#hotmail.com', 'h');
insert into #emails values (2, 'bill#hotmail.com', 't');
insert into #emails values (2, 'bill#gmail.com', 'h');
select * from #emails
drop table #emails
Thanks
This is based on the description of the logic, not the sample results.
I think you want boolean logic in the where clause:
where (email like '%#company.com' and type = 'h') or
(email not like '%#company.com' and type = 't')
This particular version assumes that email is never NULL. It is easy enough to incorporate that into the logic.
EDIT:
I see, this is a prioritization query:
select top (1) with ties e.*
from #emails e
order by row_number() over (partition by personId
order by (case when email like '%#company.com' and type = 'h' then 1
when type = 't' then 2
else 3
end)
);
You can exclude type column from the insert and use a computed field instead, as below:
create table #emails (personId int, email nvarchar(100), type as case when email like '%#company.com' then 'h' else 't' end)
Like that all your inserts will automatically have the type column handled
EDIT: If you still want to perform an update after words just use the same CASE statement in the select.
It's kinda hard to understand the question, but I think you are looking for something like this:
SELECT personId, email, type
FROM #emails t0
WHERE type = CASE WHEN EXISTS(
SELECT 1
FROM #emails t1
WHERE t0.personId = t1.personId
AND t1.email LIKE '%#company.com'
) THEN 'h' ELSE 't' END
This will give the desired results, so the text of the question should be something like "when there is a record for that person with email ends with #company.com then type h otherwise type t.
If I get it right. Your #company.com is a default value to email column. So, you want to get the actual email, which will be the next email for each person. I'm not sure about the type column why you're trying to using it, as (in my opinion) doesn't matter if is it h or t as long as we can exclude emails that ends with #company.com directly with this simple query :
SELECT *
FROM #emails
WHERE
RIGHT(email, 11) <> 'company.com'
from there you can expand the where clause as much conditions as needed.

isnull function does not return correct

When I am using isnull it does not return the '' please see below I have original DOB, isnull used, cast as date.
You would need to convert dob to a char/nchar/varchar/nvarchar type to use isnull() or coalesce() like that.
select isnull(convert(varchar(10),dob,120),'')
if you really would like to return an empty string for the date value, you could try this in a new query window. It creates a table to repoduce your requirement of a null date value and then selects the value before dropping the table.
CREATE TABLE dbo.Test
(
Id INT IDENTITY(1,1) NOT NULL
,Date1 DATE NULL
)
INSERT INTO dbo.Test(Date1) VALUES ('01/01/2017')
INSERT INTO dbo.Test(Date1) VALUES ('01/02/2017')
INSERT INTO dbo.Test(Date1) VALUES (NULL)
INSERT INTO dbo.Test(Date1) VALUES ('01/04/2017')
SELECT * FROM dbo.Test
SELECT Date1 = CASE WHEN date1 IS NULL THEN '' ELSE CAST(DATE1 AS VARCHAR(10)) END from dbo.Test
DROP TABLE dbo.Test
go

How to allow temporary tables to accept null values

If you create temp tables using "insert into" in SQL Server it uses the first insert to determine whether a column accepts null value or not. if the first insert has null value the column become nullable otherwise it will be non-nullable.
Is there a way to create temp tables using "insert into" to accept null values?
Example
This works without any problem
Select 'one' as a , null as b
into #temp
insert into #temp
Select 'two' as a , 500 as b
However this throws "Cannot insert the value NULL into column 'b'"
Select 'one' as a , 500 as b
into #temp
insert into #temp
Select 'two' as a , null as b
I know I could do create Table or alter column statement but I want to do it without rewriting hundreds of the existing queries.
How about this?
Select CONVERT(varchar(100), 'one') as a , CONVERT(int, 500) as b
into #temp
insert into #temp
Select 'two' as a , null as b
select * from #temp order by 1
I would workaround this by explicitly creating temporary table before first insert.
create table #temp (a varchar(10) not null, b int null)
(Un)fortunately, this question is too popular and appears at the top for Sybase ASE 15.7 as well, so just adding my answer for Sybase here.
For me neither of cast, convert or coalesce worked, but a case statement did (which is what coalesce is, but eh...)
select
a = case when 1 = 0 then null else 'one' end,
b = case when 1 = 0 null else 500 end
into #temp
This is an old question but I had a similar issue where I UNION NULLs to the initial query which may have helped the OP.
Select 'one' as a , 500 as b
into #temp
UNION
SELECT NULL, NULL
insert into #temp
Select 'two' as a , NULL as b
Putting it here so the next time I need to do this and forget how...

INSERT INTO With a SubQuery and some operations

I'm trying to insert some data to a table contains two things : "a string" and "maximum number in Order column + 1".
This is my query:
INSERT INTO MyTable ([Text],[Order])
SELECT 'MyText' , (Max([Order]) + 1)
FROM MyTable
What is going wrong with my query?
I'm using Microsoft SQL Server 2005 SP3.
You can test this query like this:
I don't receive error:
create table #MyTable
(
[Text] varchar(40),
[Order] int NOT NULL
)
INSERT INTO #MyTable([Text],[Order])
SELECT 'MyText' [Text], isnull(max([order]) + 1, 0) [Order]
FROM #MyTable
drop table #MyTable
Original:
INSERT INTO MyTable ([Text],[Order])
SELECT 'MyText' [Text], max([Order]) + 1 [Order]
FROM MyTable
or
INSERT INTO MyTable ([Text],[Order])
SELECT top 1 'MyText' [Text], max([Order]) + 1 [Order]
FROM MyTable
limit is not valid in SQL Server as far as I know.
Cannot insert the value NULL into column 'Order', table 'master.dbo.MyTable'; column does not allow nulls. INSERT fails. The statement has been terminated.
This means that the Order column isn't allowed to be null, and that the Max([Order]) + 1 part of your column returns NULL.
This is because your table is empty, as you already noticed by yourself.
You can work around this by replacing NULL by a real number in the query, using ISNULL():
INSERT INTO MyTable ([Text],[Order])
SELECT 'MyText' , (isnull(Max([Order]),0) + 1)
FROM MyTable
Unless he has a column named OrderBy
then he would have to add / assign all values within that Insert especially if the column does not allow for nulls
sounds like fully qualifying the Insert with the dbo.MyTable.Field may make more sense.
also why are you naming fields with SQL Key words...???
INSERT INTO MyTable ([Text],[Order] Values('MyTextTest',1)
try a test insert first..