I need this case statement to return an empty string if the value is null or -1 however it's actually returning 0. EmployeeCount is an int and I'm assuming it needs to be cast to varchar but nothing I've tried seems to be working.
CASE
WHEN EmployeeCount = -1 THEN ''
WHEN EmployeeCount IS NULL THEN ''
ELSE EmployeeCount
END
this not working either:
CASE
WHEN EmployeeCount = -1 THEN ''
WHEN EmployeeCount IS NULL THEN ''
ELSE CAST(EmployeeCount as varchar(10))
END
A case expression returns a single type. If you have some then clauses evaluate to strings and others evaluate to numbers, database will decide that the result is a number, not a string. That is why you are seeing 0. That is what '' looks like when converted to a number.
The solution is simple: cast() the result to a string:
(CASE WHEN EmployeeCount = -1 OR EmployeeCount IS NULL THEN ''
ELSE CAST(EmployeeCount as VARCHAR(32))
END)
I tried this in SQL Server Management Studio:
SELECT
CASE
WHEN EmployeeCount = -1 THEN ''
WHEN EmployeeCount IS NULL THEN ''
ELSE CAST(EmployeeCount as varchar(10))
END
AS COL1
FROM
(SELECT -1 as EmployeeCount) t
... and it does return empty string, not 0, so there's nothing wrong with the SQL, something outside of SQL is converting it to 0.
Related
In this project I'm currently working on (I'm building a bridge between a desktop app and a new e-shop) there is a products table that has some spare columns defined that can be used for whatever reason the end user might need some custom data to be stored into.
So, the user needed to set a true/false flag to determine whether the products would appear in three different sliders... Unfortunately, the person who implemented this, didn't even use the same type of spare columns... So,
Slider1's flag is stored in a varchar(50) column
Slider2's flag is stored in a float column
Slider3's flag is stored in a float column
Additionally I ran a SELECT DISTINCT <column> for each one of them to get an idea of the actual data stored in each column and got the following results:
The varchar column has the following data stored in it:
FLDSTRING1
NULL
''
0
1
194276400456
The float column has the following data stored:
FLDFLOAT5
NULL
0
1
And the other float column has this:
FLDFLOAT6
NULL
1
Also, I ran the following query to find the different combinations of the data stored for each column:
SELECT FLDSTRING1, FLDFLOAT5, FLDFLOAT6
FROM MATERIAL
GROUP BY FLDSTRING1, FLDFLOAT5, FLDFLOAT6
and got the following combinations...
FLDSTRING1
FLDFLOAT5
FLDFLOAT6
NULL
NULL
NULL
NULL
NULL
1
NULL
0
NULL
NULL
1
NULL
NULL
1
1
''
NULL
NULL
''
NULL
1
0
NULL
NULL
0
0
NULL
1
NULL
NULL
1
NULL
1
1
0
NULL
1
1
NULL
1
1
1
194276400456
0
NULL
What I need after all this introduction...
I want a concatenated string of three comma-separated values like this
NEWPROD for when FLDSTRING1 would evaluate to true - anything not NULL, 0, or ''
CUSTOM1 for when FLDFLOAT5 would evaluate to true - basically the value 1
CUSTOM2 for when FLDFLOAT6 would evaluate to true - again value 1
After some trial and error I managed to bring this to a point that it kind of works, in the sense that it brings the correct values, not comma-separated though...
SELECT
FLDSTRING1, FLDFLOAT5, FLDFLOAT6,
CONCAT(CASE WHEN ISNULL(FLDSTRING1, '') = '' THEN '' ELSE 'NEWPROD' END,
CASE WHEN ISNULL(FLDFLOAT5, '') = '' THEN '' ELSE 'CUSTOM1' END,
CASE WHEN ISNULL(FLDFLOAT6, '') = '' THEN '' ELSE 'CUSTOM2' END) AS TAGS
FROM
MATERIAL
GROUP BY
FLDSTRING1, FLDFLOAT5, FLDFLOAT6;
FLDSTRING1
FLDFLOAT5
FLDFLOAT6
TAGS
NULL
NULL
NULL
NULL
NULL
1
CUSTOM2
NULL
0
NULL
NULL
1
NULL
CUSTOM1
NULL
1
1
CUSTOM1CUSTOM2
''
NULL
NULL
''
NULL
1
CUSTOM2
0
NULL
NULL
NEWPROD
0
0
NULL
NEWPROD
1
NULL
NULL
NEWPROD
1
NULL
1
NEWPRODCUSTOM2
1
0
NULL
NEWPROD
1
1
NULL
NEWPRODCUSTOM1
1
1
1
NEWPRODCUSTOM1CUSTOM2
194276400456
0
NULL
NEWPROD
Problem #1 is I don't quite understand how this works... I mean, value 0 isn't '', but still for the combination of NULL 0 NULL I get an empty value, which is what I wanted... But how does it do that?
And also, can someone update my final query to comma-separate the calculated TAGS column? Problem #2 is that I don't want it to contain just two commas, like ,,, when the combination wouldn't justify any of the three values to appear... It should work like PHP's implode() works...
To help you help me with this, I'm including a fiddle with the setup of the scenario I describe here... Thanks in advance!
Since you are using SQL Server 2014, instead of CONCAT_WS you may try STUFF as shown below. By prepending the delimiter , before all strings ,the STUFF will remove the first comma found.
SELECT
FLDSTRING1,
FLDFLOAT5,
FLDFLOAT6,
STUFF(
CONCAT(
CASE WHEN FLDSTRING1 IS NULL OR FLDSTRING1 IN ('0','') THEN '' THEN '' ELSE ',NEWPROD' END,
CASE WHEN FLDFLOAT5 IS NULL THEN '' ELSE ',CUSTOM1' END,
CASE WHEN FLDFLOAT6 IS NULL THEN '' ELSE ',CUSTOM2' END
),
1,1,''
) AS TAGS
FROM #MATERIAL
GROUP BY FLDSTRING1, FLDFLOAT5, FLDFLOAT6;
View working demo db fiddle
Let me know if this works for you.
Use the CONCAT_WS() function to concat values into a comma (or other separator) separated list, which ignores nulls.
To use CONCAT_WS(), you want to pass it a true NULL if the value is "blank" (by your definition), otherwise your custom label:
SELECT DISTINCT
FLDSTRING1,
FLDFLOAT5,
FLDFLOAT6,
CONCAT_WS(',',
CASE WHEN FLDSTRING1 IS NULL OR FLDSTRING1 = '' OR FLDSTRING1 = '0' THEN NULL ELSE 'NEWPROD' END,
CASE WHEN FLDFLOAT5 IS NULL OR FLDFLOAT5 = 0 THEN NULL ELSE 'CUSTOM1' END,
CASE WHEN FLDFLOAT6 IS NULL OR FLDFLOAT6 = 0 THEN NULL ELSE 'CUSTOM2' END) AS TAGS
FROM MATERIAL
Replaced GROUP BY with DISTINCT because it's simpler and (here) achieves the same thing.
If CONCAT_WS is not available:
SELECT DISTINCT
FLDSTRING1,
FLDFLOAT5,
FLDFLOAT6,
REPLACE(REPLACE(REPLACE(CONCAT(
CASE WHEN FLDSTRING1 IS NULL OR FLDSTRING1 = '' OR FLDSTRING1 = '0' THEN 'X' ELSE 'NEWPROD' END,
',',
CASE WHEN FLDFLOAT5 IS NULL OR FLDFLOAT5 = 0 THEN 'X' ELSE 'CUSTOM1' END,
',',
CASE WHEN FLDFLOAT6 IS NULL OR FLDFLOAT6 = 0 THEN 'X' ELSE 'CUSTOM2' END
), ',X', ''), 'X,', ''), 'X', '') AS TAGS
FROM MATERIAL
See dbfiddle.
I recently read a SQL code snippet which confuses me.
declare #test nvarchar(100) = NULL
select
case
when #test <> '' then 1
else 0
end
I was quite confident that the result will be 1, since I think NULL is not equivalent to an empty string. However, the actual output is 0.
(I'm using MS SQL Server 2012 on Windows 7 64-bit)
As far as I understand, '' is an empty string which indicates the value contains 0 character, and Null means the data is in absence. But now I'm not sure about this. Can anyone help me to sort it out? Is this some exemption case?
When you use NULL for your comparison, it always will return NULL/unknown so, in fact is not true, so is false.
To analyze a NULL field you must use IS NULL
select
case
when #test IS NULL then ....
when #test <> '' then ....
else ....
end
or you can re-write your query as follow:
select
case
when #test IS NULL or #test = '' then ...
when #test <> '' then ....
end
Null doesn't equal ''.
Null is the absent of a value.
Null also doesn't equal Null so SELECT 1 where NULL = NULL will also return nothing.
Use this instead.
declare #test nvarchar(100) = NULL
select case when #test IS NULL then 1
else 0
end
Use something like this:
declare #test nvarchar(100) = NULL
select case when #test <> '' OR #test IS NULL then 1
else 0
end
NULL is not the same as ''. Just like NULL is not the same as 0. NULL is a special value used to indicate that no value of the datatype is being stored.
If you want to COALESCE the NULL to a concrete value, you can use the ISNULL or the COALESCE functions in SQL Server.
DECLARE #test NVARCHAR(100) = NULL
SELECT
CASE
WHEN ISNULL(#test, N'') <> N'' THEN
1
ELSE
0
END
I have a case inside my stored procedure which I use before executing the data.
DECLARE #Setup nvarchar(50)
SELECT
#ZipCode = CASE
WHEN REPLACE(#ZipCode, '0', '') = ''
THEN NULL ELSE #ZipCode
END,
#ZipCodeEND = CASE
WHEN REPLACE(#ZipCodeEND, '0', '') = ''
THEN NULL ELSE #ZipCodeEND
END,
SELECT
#Setup = CASE WHEN (LEN(ISNULL(#ZipCode, ''))) > 0 THEN '1' ELSE '0' END +
CASE WHEN (LEN(ISNULL(#ZipCodeEND,''))) > 0 THEN '1' ELSE '0' END
IF ISNULL(#ID, 0) = 0
BEGIN
INSERT INTO dbo.MapToStaticValuesTable(ZipCode, ZipCodeEND, Setup)
VALUES(#ZipCode, #ZipCodeEND, #Setup)
END
The problem here is even if zipcode and zipcodeEnd are empty and set to null after being saved into the table I keep getting the value "11" instead of getting "00".
Now if I do the same example with nvarchar values it would work, but since ZipCode and ZipCodeEnd are set to int it's acting weird.
It is acting weird because you are using string functions on integers. Not sure what you are trying to achieve with your code but I'm sure it can be done just by checking the values as integers.
I guess this could be what you are looking for.
select case when nullif(#ZipCode, 0) is null then '0' else '1' end +
case when nullif(#ZipCodeEND, 0) is null then '0' else '1' end
One example of weird
select isNull(#ZipCode, '')
return 0 if #ZipCode is null.
Here i try to convert a bit value to varchar , i try this query in MS sql server
CASE WHEN cast(ISNULL(O.isTerminated,0)as varchar) = 1 THEN 'Yes' ELSE '' END AS isTerminated.
Is giving error "Conversion failed when converting the varchar value 'Yes' to data type bit."
what will be the solution for this.
The error is not caused by the statement you are showing but by what you do with your isTerminated alias afterwards.
Your statement as is doesn't throw any errors.
DECLARE #isTerminated BIT = 1
SELECT CASE WHEN CAST(ISNULL(#isTerminated, 0) AS VARCHAR) = 1
THEN 'yes'
ELSE ''
END AS isTerminated
But treating the aliased isTerminated as a bit does.
DECLARE #isTerminated BIT = 1
SELECT *
FROM (SELECT CASE WHEN CAST(ISNULL(#isTerminated, 0) AS VARCHAR) = 1
THEN 'yes'
ELSE ''
END AS isTerminated) t
WHERE isTerminated = 1 -- isTerminated is a VARCHAR at this point
Why are you casting the bit to a varchar. Can you just do this:
CASE WHEN ISNULL(O.isTerminated,0) = 1 THEN 'Yes' ELSE '' END AS isTerminated
EDIT
When trying this example.
DECLARE #T TABLE(isTerminated BIT)
INSERT INTO #T
VALUES(1),(NULL),(0)
SELECT
CASE WHEN ISNULL(O.isTerminated,0) = 1 THEN 'Yes' ELSE '' END AS isTerminated
FROM
#T AS O
With your case statement. I don't revise a error. Are you missing out any details?
I have a table containing Remarks as a column. Now i have to display the data inside remarks as 0 if the row is blank i.e empty but not Null. Please give me a query that will solve my problem in MS SQL server 2005.
Use SELECT ... CASE
SELECT remarksDisplay = CASE remarks WHEN '' THEN '0' ELSE remarks END
FROM tableName;
use a case statement in your SQL i.e
select (case when Remarks = '' then '0' else Remarks end) as Remarks from RemarksTable
You can further extend this to handle null values too if you want i.e
select (case when isnull(Remarks, '') = '' then '0' else Remarks end) as Remarks from RemarksTable
SELECT
case column1
when '' then 'unknown' /*empty*/
when ' ' then 'unknown' /*empty with space*/
end
FROM table