how to show empty value for a int datatype in SQL? - sql

how to show empty value for a int datatype in SQL?
I have a case statement on an int datatype column to show empty for the values less than or equal to 0.
case when [TotalValue] <= 0 Then ''
when [TotalValue] > 0 Then [TotalValue]
End as [TotalValue]
Right now, case statement is returning 0 for any values less than or equal to 0. I expect to have them as Empty. Having 0 instead of negative value is not a correct result.
How to convert the record to show only empty?

The problem of your code is that Then '' is automatically converted to int value, which happens to be 0 for empty strings (try select CAST('' as int) to check).The data type for ambiguously defined column (like yours) is determined from the data type precedence rules.
Unambiguously defining the data type of the column would resolve the issue.
I recommend trying to return NULL from the database, like this:
case when [TotalValue] <= 0 Then NULL
when [TotalValue] > 0 Then [TotalValue]
End as [TotalValue]
Most likely, your report engine will convert NULL to something like an empty string. In addition, you may be getting some benefits of ability to manipulate numeric values, if your report engine supports those (e.g. calculate average over selection).
Alternatively, try casting the values to string in SQL:
case when [TotalValue] <= 0 Then ''
when [TotalValue] > 0 Then CAST([TotalValue] as varchar)
End as [TotalValue]

I think the simplest construct is:
(case when TotalValue > 0 Then TotalValue
end) as TotalValue

You can always CAST the number to a VARCHAR (string) and then set it to an empty string when NULL:
ISNULL(CAST(TotalValue as varchar(10)),'') as TotalValue

Empty string is a concept that doesn't make sense for integer datatype.
Generally you should return the results to the application as integer datatype and use NULL for this and have your application display null as an empty string if desired.
If you do need to do this in SQL you are now dealing with strings rather than integers.
One way of converting to string and performing your desired formatting is with the FORMAT function.
SELECT FORMAT(TotalValue, '0;"";""')
FROM
(VALUES (1),
(0),
(-123),
(123456))T(TotalValue)
Returns
1
123456

Related

SQL - How to sort numbers in a VARCHAR column with empty strings as entries

I have a postgres column which is like so:
It only has numbers or empty string.
I want to be able to sort the numbers by the numbers but as I go to cast the column to a float, it will give me the following error:
ERROR: invalid input syntax for type double precision: ""
Is there a way I can do this sort, and having the empty strings be treated as 0?
This is my query that's failing:
SELECT C.content
FROM row R
LEFT JOIN cell C ON C.row_id = R.row_id
WHERE R.database_id = 'd1c39d3a-0205-4ee3-b0e3-89eda54c8ad2'
AND C.column_id = '57833374-8b2f-43f3-bdf5-369efcfedeed'
ORDER BY cast(C.content as float)
when its an empty string you need to either treat it as null or 0 and then it will work, try putting a case statement like so in the order by
ORDER BY
case when C.content = '' then 0
else cast(C.content as float)
end
If it's sure this column will never have negative values, a simple option is just adding a leading zero.
If the column is NULL or has an empty string, it will be sorted as 0.
Otherwise, the value will be sorted as it is because adding a leading zero doesn't change anything.
SELECT yourcolumn
FROM yourtable
ORDER BY CAST(CONCAT('0',yourcolumn) AS FLOAT);
If negative values can appear, this would fail, so I would then use CASE WHEN.
But I propose to also take 0 for NULL values, not only for empty strings:
SELECT yourcolumn
FROM yourtable
ORDER BY
CASE WHEN yourcolumn = '' OR yourcolumn IS NULL
THEN 0
ELSE CAST(yourcolumn AS FLOAT)
END;
Otherwise, NULL values would be sorted as highest number which is likely not intended.
And yes, I know you wrote there are numbers and empy strings only in your table, but maybe this can change (unless the column is not nullable). So adding this condition doesn't hurt.

When using cast - error: invalid input syntax for type numeric: "" (postgreSQL)

Duration column in the table is given with 'varchar' data type. It contains decimal values. So I am trying to cast varchar to float/numeric/decimal/double/double precision. But none of those works. why is it not working?
select runner_id,
sum(case when cast(duration as decimal) <> '' then 1
else 0 end) as delivered, count(order_id) as total_orders
from t_runner_orders
group by runner_id
The reason it's not working is because your duration column contains values which cannot be cast to a numeric type. The specific value throwing the error is an empty string. Also, you shouldn't be comparing a numeric type to an empty string.
Also, if you're comparing a varchar column to a character value in your CASE statement, why are you trying to cast it to a numeric type at all?
For what you're doing here, I would just write it as CASE WHEN duration <> '' THEN 1 ELSE 0 END
And if you do need to cast it to a numeric type at some point, the way to do that would be something like CASE WHEN duration = '' THEN NULL ELSE cast(duration AS DECIMAL) END (asuming that empty strings are the only values in your column which cannot be cast to decimal)
The problem is you are doing the CAST before the <> ''. The cast fails as there are empty strings in the field. You have several choices:
Use NULL instead of '' in field.
Do duration <> ''
Last and probably the best long term solution change the column type to numeric.
You can translate '' to null using NULLIF in the cast.
cast(nullif(duration,'') as decimal) is not null
However this will not solve you basic problem which is "varchar' data type. It contains decimal values" NO it does not it contains a string which you hope are decimal values, but nothing prohibits putting 'zero.zero' into it - distinctly not a decimal value. I will go #AdrianKlaver one step further.
3. The only long term solution change the column type to numeric.

Updating with case in SQL Server 2008 R2

I want to update a column according to another column value.
for example, In Value column i have numbers between 0 to 1.
I want to check values and if:
Values < 0.45 set ValueStatus=Bad
Values >=0.45 and values<0.55 set ValueStatus =SoSo
Values >= 0.55 set ValueStatus=Good
I wrote the query like this:
update table
set ValueStatus=(case
when Values<'0.45' then 'Bad'
when (Values>='0.45' and Values<'0.55') then 'SoSo'
when Values>='0.55' then 'Good'
else Values
end)
But i get this error :
Error converting data type varchar to float.
Type of Values is Float and ValueStatus is Nvarchar(50)
Thanks
try this (you were adding ' to the numbers and SQL takes them as varchar) :
update table
set ValueStatus=(case when Values<0.45 then 'Bad'
when Values>=0.45 and Values<0.55 then 'SoSo' when Values>=0.55
then 'Good' else Values end )
I believe your problem is based on how the case statement determines the return type. You can read about it here and here.
The numeric types have a higher precedence than the string types. With the else values, you have four clauses in the `case. Three return strings; one returns a number. The number trumps the types so it tries to turn everything into a number.
You can mimic this problem with:
select (case when 1=1 then 'abc' else 12.3 end)
Happily, you can fix this by removing the else clause which is not needed in this case.

SQL server casting string to integer checking value before casting

I have a table with a field named MINIMUM_AGE. The values stored in this field are of type nvarchar:
17 years
54 years
N/A
65 years
I would like to apply a WHERE clause on the column to check for a certain age range. To do that I need to parse out the age from the field values.
So, I think I need to select the first two characters, then cast them into an integer. Also, some fields may not contain numbers for the first two characters. Some may simply be N/A. So, I will need to check for that before casting.
Can someone explain how to accomplish this?
Here is the SQL Fiddle that demonstrates the below query:
SELECT CASE
WHEN MINIMUM_AGE <> 'N/A'
THEN CAST(LEFT(MINIMUM_AGE, 2) AS int)
ELSE 0
END
FROM MyTable
Note: the CASE expression can only return one data type. So, in the example above if the MINIMUM_AGE is N/A then it returns 0.
If you would rather have it return null, then use the following:
SELECT CASE
WHEN MINIMUM_AGE <> 'N/A'
THEN CAST(LEFT(MINIMUM_AGE, 2) AS int)
END
FROM MyTable

Does SQL Server really evaluate every 'then' clause in a case expression?

I'm working with an ItemNumber field in a legacy system that is 99% numbers, but there are a few records that contain letters. The numbers are all padded with leading zeros so I thought I would just cast them as bigint's to solve this problem, but of course it throws an error when it gets to the records with letters in them.
I thought the following case statement would have worked, but it still throws the error. Why in the world is SQL Server evaluating the cast if the isnumeric(itemnumber) = 1 condition isn't true?
select case when isnumeric(itemnumber) = 1
then cast(itemnumber as bigint)
else itemnumber
end ItemNumber
from items
And what's the best workaround?
Your expression tries to convert a VARCHAR value into a BIGINT if it's numeric and leave the value as is if it's not.
Since you are mixing datatypes in the CASE statement, SQL Server tries to cast them all into BIGINT but fails on non-numeric values.
If you just want to omit non-numeric values, get rid of the ELSE clause:
SELECT CASE ISNUMERIC(itemnumber)
WHEN 1 THEN
CAST(itemnumber AS BIGINT)
END
FROM items
Maybe because:
ISNUMERIC returns 1 for some characters that are not numbers, such as plus (+), minus (-), and valid currency symbols such as the dollar sign ($). For a complete list of currency symbols, see money and smallmoney (Transact-SQL).
http://msdn.microsoft.com/en-us/library/ms186272.aspx
The problem is that you are still mixing your types:
select case when isnumeric(itemnumber) = 1
then cast(itemnumber as bigint) --bigint
else itemnumber --varchar or whatever
end ItemNumber --????
from items
You need two columns
select case when isnumeric(itemnumber) = 1
then cast(itemnumber as bigint) --bigint
else -1
end NumericItemNumber
from items
select case when isnumeric(itemnumber) = 1
then ''
else itemnumber
end StringItemNumber
from items
Then you need to build a query that takes both ints and varchars