I'm having trouble figuring this statement out. It seems that SQL Server is still executing the THEN part in the CASE WHEN statement. Please see this query.
SELECT
CASE
WHEN ISNUMERIC('INC') = 1
THEN CAST('INC' as numeric(10,2))
ELSE 'FALSE'
END AS foo
SQL Server is returning
"Error converting data type varchar to numeric"
From this query it should return FALSE and not return an Error since the THEN part was not executed.
What is wrong with my query?
The problem is that you are returning two different data types from the same column. So try this one -
DECLARE #value CHAR(3)
SET #value = 66
SELECT
CASE WHEN ISNUMERIC(#value) = 1
THEN CAST(CAST(#value AS NUMERIC(10,2)) AS VARCHAR(30))
ELSE 'FALSE'
END AS foo
That is because, your query is trying to
CAST 'FALSE' as Numeric(10,2)
Try this
SELECT CASE WHEN ISNUMERIC('INC') = 1 THEN
CAST(CAST('INC' as numeric(10,2)) AS varchar(5))
ELSE 'FALSE' END AS foo
The problem is that one branch of you CASE branches returns VARCHAR and the other a number.
Try the following:
CASE WHEN ISNUMERIC('INC') = 1
THEN CAST(CAST('INC' AS NUMERIC(10,2)) AS NVARCHAR)
ELSE 'FALSE'
END AS foo
Related
I am stuck with a table that has a column, [Renewal] that was set as a nvarchar(255),null. Not my handiwork and I cant change it. I now need to use this column in a calculation. Below as close as I can get with doing it in one statement but I cant get past the "incorrect syntax near..." error after the ELSE statement. If it ran into an issue trying to CAST as INT I would want it to continue with the rest of the records and not hose the whole query. I suppose I could add an additional column thats INT, not null and write an update statement to run prior to this but I fear I would run to the same issue. I am more UI guy than SQL guy, any suggestions? It would run on SQL Server 2008R. Thank you in advance
UPDATE C
SET [ExpirationDate] = DATEADD(MONTH,
(CASE WHEN ISNUMERIC(C.Renewal)= 1
THEN CAST(C.Renewal AS INT)
ELSE 0)
, [ExpirationDate])
FROM dbo.MyTable C
WHERE C.MyCondition = 'True'
You are missing END in CASE statement
UPDATE C
SET [ExpirationDate] = Dateadd(MONTH, ( CASE
WHEN Isnumeric(C.Renewal) = 1 THEN Cast(C.Renewal AS INT)
ELSE 0
END ), [ExpirationDate])
FROM dbo.MyTable C
WHERE C.MyCondition = 'True'
Filter the records with only numeric values and apply DATEADD function instead of adding 0 months
Also ISNUMERIC is not preferred. ISNUMERIC returns 1 if the string can be converted to any one of ints, numeric/decimal, float, or money.
https://connect.microsoft.com/SQLServer/feedback/details/302466/isnumeric-returns-true-for-and
UPDATE C
SET [ExpirationDate] = DATEADD(MONTH,CAST(C.Renewal AS INT), [ExpirationDate])
FROM dbo.MyTable C
WHERE C.MyCondition = 'True'
AND C.Renewal NOT LIKE '%[^0-9]%'
This would be more straightforward.
UPDATE C
SET [ExpirationDate] = DATEADD(MONTH, CAST(c.Renewal AS INT), [ExpirationDate])
FROM dbo.MyTable C
WHERE C.MyCondition = 'True'
AND ISNUMERIC(c.Renewal) = 1
Is there anyway that I can change column name through THEN clause in CASE STATEMENT. This is how my code looks but it is not working.
SELECT
CASE
WHEN #IDWeeklySpecial = '107'
THEN
CASE
WHEN ISNULL(v.blnLeftHandDrive, 0) = 1
THEN [HANDEDNESS] = 'LHD'
ELSE [HANDEDNESS] = 'RHD'
ELSE
CASE
WHEN ISNULL(v.blnLeftHandDrive, 0) = 1
THEN STEERING = 'LHD'
ELSE STEERING = 'RHD'
END
END
I want this result
My Ideal Result
Is this achievable? If so how?
No, it's not possible... if you are asking about dynamically modifying the column name in the resultset.
The CASE expression returns a value. To a specify the column name in the resultset, assign an alias.
SELECT CASE ... END AS mycolname
, ...
FROM ...
The column name is determined when the statement is parsed and prepared. The execution of the statement cannot modify the column name.
(It's possible I didn't understand the question. It's not clear what OP is tying to achieve.)
case is an expression. You can name the column before or after an expression, but not in the middle.
Also, a SQL statement needs to return a fixed set of columns, including the column name.
So, you cannot do what you want with a simple SQL statement. You could use dynamic SQL:
declare #sql nvarchar(max);
set #sql = '
SELECT (CASE WHEN COALESCE(v.blnLeftHandDrive, 0) = 1
THEN 'LHD'
ELSE 'RHD'
END) as [columnname]
. . . ';
set #sql = replace(#sql, '[columnname]',
(case when #IDWeeklySpecial = '107' then 'HANDEDNESS' else 'STEERING' end)
);
exec sp_executesql #sql;
Note that the . . . is for the rest of your SQL query.
I can't digest your select statement, but assume its inline case
SELECT item_name = CASE WHEN item_name = 'sometext' THEN item_id ELSE item_name END AS MyColumnName
It is not possible to assign differing column names in your query, because all vertical data values in the result set belong to the same column.
If you are just trying to alias a column name while using the CASE expression, ensure that the AS is used after the END keyword. Others have mentioned this, but it was the problem in my case. Changed it to something like this and it worked:
CASE
WHEN table1.Name LIKE '%John%' THEN 'Some John Person'
WHEN table1.Name <> 'NULL' THEN table1.Name
ELSE 'Nobody'
END AS NewAliasColumnName
I recently ran into this pickle with the CASE-THEN-ELSE statement in SQL Server (2014 if it matters), to be more accurate, "the Simple" vs "the Searched" CASE expression. Until now, I thought that the only difference between these 2 is simply the format and/or the habit in writing both ways of the case expression but I guess I was completely wrong :)
MSDN Link
The CASE expression has two formats:
The simple CASE expression
compares an expression to a set of simple expressions to determine the
result.
The searched CASE expression evaluates a set of Boolean
expressions to determine the result.
Here is the example:
set nocount on
declare #test nvarchar(50) = null
select
#test as [The NULL Value],
case
when #test is null
then null
else 'Not Null???'
end as [As Expected],
case #test
when null
then null
else 'Not Null???'
end as [The Pickle]
And the result is:
The NULL Value As Expected The Pickle
-------------------------------------------------- ----------- -----------
NULL NULL Not Null???
Could someone provide a link to a MSDN documentation where this is explained, perhaps in a more detailed manner? :)
P.S.: I bet a lot of you folks were certain that both results would yield the same output :D
It's not weird at all ...
The "shortcut" way of
case #test
when null
then null
else 'Not Null???'
end as [The Pickle]
evaluates the variable/column (here: #test) against the values in the WHEN clauses (when null) with the regular equality operator - and comparing NULL using the standard equality operator (#test = null) is always undefined/NULL itself (standard SQL behavior), so it's not true
Therefore you are getting this result - Not Null??? - for your column The Pickle
If you want to check for NULL, you must use IS NULL like in your first example...
declare #t int =1
--simple case
select
case #t
when 1 then 1 else null end
The above query is expanded to below form..
select
case when #t=1 then 1 else null end
so a query with null will expand to below
declare #t int=null
select case #t
when null then null else 'notnull' end
is expanded to
select case when #t=null then null else 'notnull' end
which obviously evaluates to not null..
So in summary only in null case you will not get results you are expecting,try below to see
declare #t int=null
declare #t1 int =1
select
case when #t is null then null else 'notnull' end as 'Searchedcase',
case #t when null then null else 'notnull' end as'simple case',
case when #t1 =1 then 1 else null end as 'Searchedcase for value',
case #t1 when 1 then 1 else null end as'simple case for value'
See discussion of NULL and UNKNOWN from Transact-SQL reference to get a handle on why '=' doesn't work for NULL.
Simple CASE must be implicitly using '=', rather than IS NULL. So to make IS NULL explicit, use a Searched CASE expression.
Maybe Microsoft will add some functionality to the simple CASE expression to if NULL is encountered, then operator 'IS' is used?
This is for SQL Server 2012 database...
I'm reading a varchar data column from a table, and depending on user-selected options the data could be either alphanumeric or numeric. I need to sort by this column so I'm trying to use a case statement, but it doesn't seem to be working. Below is a simplified example of what I'm doing, but as you can see, it's falling through to the Else of the case statement in both scenarios...any ideas on what I'm doing wrong?
Select '1st Grade Math' topic Into #temp
Declare #rptView int
Set #rptView = 1
Select Case #rptView
When 1 Then topic
Else cast(topic as int)
End
From #temp
Order by Case #rptView
When 1 Then topic
Else cast(topic as int)
End
Select Case
When #rptView = 1 Then topic
Else cast(topic as int)
End
From #temp
Order by Case #rptView
When 1 Then topic
Else cast(topic as int)
End
drop table #temp
Consider the following example based on your table:
Select Case 1 When 1 Then topic
Else 5
End
From #temp
It also fails with the following error:
Conversion failed when converting the varchar value '1st Grade Math' to data type int.
Why? Because every expression must have a well-defined data type. SQL Server deduces that the type of your first column is int, since the ELSE clause contains an int. Thus, it tries to convert topic to int as well, which fails.
In other words: You can't do it like that. The field in your result set can be varchar or int, not both.
Adding few more examples which may help..
declare #a int=1
declare #b varchar='b'
--this works
select
case when #a=1 then #a else #b end
--this also works
select
case when #a=2 then #b else #b end
--this fails
select
case when #a=1 then #b else #a end
--this fails
select
case when #a=2 then #a else #b end
Why ..?Because of data type precedence ,SQL tries to convert everything to type with higher precedence
I have the following query which is throwing:
Arithmetic overflow error converting varchar to data type numeric.
Query:
Select
#Fee = Case
When IsNull(Fee, '') = '' Then 0.00
Else Fee
End
#Fee is of type Money, and Fee is Varchar type.
I have also observer that for following types of data in Then clause no error is being displayed.
Select #Fee = Case When IsNull(Fee, '') = '' Then 1 Else Fee End
Select #Fee = Case When IsNull(Fee, '') = '' Then 1.0 Else Fee End
So only for values 0.00 or 0.0 in Then clause I am getting error.
I have also tested with below query and worked fine:
Select #Fee = Case When IsNull(Fee, '') = '' Then Cast(0.00 as money) Else Fee End
And more interesting thing is that, as per data we have in table, Then part of the Case statement will never be executed. Please help me understanding this behavior of Case statement.
I have played around this and this is what happens:
DECLARE #v VARCHAR(20) = '1'
SELECT CASE WHEN '' <> '' THEN 0.00 ELSE #v END col1 INTO tempTable
When you will execute the above query you will see error but the table will be created and the type of the column created col1 is numeric(2,2). If you change to 0.0000 the type will be numeric(4,4). This means that actually the type of an expression depends on that value. Also (2,2) means that you can store only values with length 2 and everything goes after dot(.12, .25 etc). So it can not cast 1.00 to numeric(2,2) because the type doesn't allow to have digits before dot.
The best rule here is to always return the same types from different paths of case expression.
This is from Microsoft about return type of case expression (https://msdn.microsoft.com/en-us/library/ms181765.aspx):
Returns the highest precedence type from the set of types in
result_expressions and the optional else_result_expression. For more
information, see Data Type Precedence (Transact-SQL).
This is about type precedence where you can see that numeric precedes varchar(https://msdn.microsoft.com/en-us/library/ms190309.aspx). So the return type of your case expression becomes numeric(2,2) and this is the answer to your question.
I will also give you an advise: never store money values in varchar columns. Always store values in appropriate type(there are so many types available that all your needs will be satisfied).
You have a CASE expression that returns two different datatypes - that's always a really bad idea....
Select
#Fee = Case
When IsNull(Fee, '') = '' Then 0.00
Else Fee
End
When Fee is in fact NULL, you return 0.00 - a numerical value
When Fee (varchar) is NOT NULL, then you return that value - a string
Since both cases are assigned to one and the same #Fee variable - SQL Server must coerce these into the same datatype - whatever #Fee dictates (money in your case).
And for some reason, in the case of Fee being NOT NULL, that seems to fail at times.
So the point is: whenever possible, return the same datatype from all your possible values in a CASE statement - and do so explicitly (using a CAST or CONVERT) - don't force SQL Server to handle this for you
the code will reproduce your issue
DECLARE #Fee MONEY
DECLARE #test VARCHAR
SELECT #Fee = ISNULL(#test, 0.00)
Select #fee
but this one is the fix
DECLARE #Fee MONEY
DECLARE #test VARCHAR
SELECT #Fee = ISNULL(#test, '0.00')
Select #fee