SQL Server: casting the column datatype - sql

SQL Server 2005/ 2008
I have kept a CASE condition for a SQL query which results Float /Numeric Value. One of the CASE condition is to say N/A. I kept the piece of code.
For column : Compliance - Possible values could be N/A,100.0,99.1 ... ( nvarchar, float ).
select
x.MemberName, x.DOB, x.FilePath,
x.Medication, x.NDC, x.Directions,
x.Name, x.Strength, x.GenericName,
x.QtyOrdered, x.DaysSupply, x.DateFilled,
CASE WHEN x.test = 0 THEN 'N/A'
WHEN compliance > 100.0 THEN '100.0'
ELSE CAST(FLOOR(compliance * 10)/10.0 AS DECIMAL(3, 1))
END AS [Compliance]
Above syntax spills error as ..
Msg 8114, Level 16, State 5, Line 10
Error converting data type varchar to numeric.
How should I type cast the field ?

CASE is an expression that returns a single result and regardless of the path it always needs to result in the same data type (or implicitly convertible to the same data type). Try:
...
CASE
WHEN x.test = 0 THEN 'N/A'
WHEN compliance > 100.0 THEN '100.0'
ELSE CONVERT(VARCHAR(5), CAST(FLOOR(compliance *10)/10.0 AS DECIMAL(3,1)))
END AS as [Compliance];

You're not consistent in your CASE statement - you need to provide the same data type as result for all options.
CASE WHEN x.test = 0 THEN 'N/A'
WHEN compliance > 100.0 THEN '100.0'
ELSE CAST(FLOOR(compliance * 10)/10.0 AS DECIMAL(3, 1))
END AS [Compliance]
Since the first two options return a string ('N/A' or '100.0'), your last option also must return a string value:
CASE WHEN x.test = 0 THEN 'N/A'
WHEN compliance > 100.0 THEN '100.0'
ELSE CAST(CAST(FLOOR(compliance * 10)/10.0 AS DECIMAL(3, 1)) AS VARCHAR(20))
END AS [Compliance]

Related

Why is SQL Server trying to convert my nvarchar(20) datatype to an int?

I'm getting the "conversion" error in a SQL Select query.
The error is:
Msg 248, Level 16, State 1, Line 6
The conversion of the nvarchar value '7000952682' overflowed an int column.
Problem is, there are no int columns in my table!
Here is the table structure:
Here is the query:
If I set the value of #SU to NULL, then it does return all rows as expected. When the value is set to the string value of '7000952682' I get the error.
Why is SQL Server trying to convert the nvarchar value to an int?
All branches of a CASE expression have to have the same type. In this case (no pun intended), it looks like SQL Server is using an integer type and doing an implicit cast of SU to integer. The problem is that the max value for an integer in SQL Server is roughly 2.1 billion, and the example you gave is using the value 7000952682, hence the overflow.
You have two options here. You could make everything varchar:
CASE WHEN #SU IS NULL OR #SU = '' THEN '1' ELSE [SU] END
Or, you could make everything numeric, using a type that won't overflow, e.g.
CASE WHEN #SU IS NULL OR #SU = ''
THEN CAST(1 AS numeric(20, 6))
ELSE CAST([SU] AS numeric(20, 6)) END
As a side note, you could write the first part of your CASE expression more succinctly using COALESCE:
CASE WHEN COALESCE(#SU, '') = '' THEN '1' ELSE [SU] END
Don't use case in the where clause. The logic is more simply and accurately expressed as:
where (#su is null or #su = '' or #su = su)

SQL Server 2005 - Converting failure

I'm selecting values from a table. Inside the table there is a column called value. I'm trying to select that value with a 'g' at the end of the value when the value is a number. However, when i try to do this i get the following error (see below).I think this is because i'm using ISNUMERIC, and since the values are either a string representation of a number or the string value 'None' (i know weird, but i have to have this way), i get a convert failure. Anyone know how to fix this issue in SQL Server 2005
Error
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'None' to data type int.
Query
SELECT a.student_assignment_id,
a.student_id,
a.location_id,
a.assignment_type,
(
Case
WHEN a.assignment_type = 'HW' THEN
CASE a.value
WHEN ISNUMERIC(a.value) THEN RTRIM(a.value)+'g'
ELSE a.value
END
ELSE a.value
END
) as value
,
a.start_date,
a.end_date,
a.course,
a.created_by,
a.creation_date,
a.modified_by,
a.modified_date,
You need to use CASE WHEN ISNUMERIC(a.value) = 1 instead of CASE a.value WHEN ISNUMERIC(a.value)
CASE WHEN a.assignment_type = 'HW'
THEN
CASE WHEN ISNUMERIC(a.value) = 1
THEN RTRIM(a.value)+'g'
ELSE a.value
END
ELSE a.value
END
ISNUMERIC() returns a boolean 0 (not numeric) or 1 (numeric), so your current query is attempting to compare the string a.value to an int (0 or 1)

even after converting it to varchar it is giving error: Error converting data type varchar to float,

SELECT a.[Emp_No],
a.[Emp_Name],
a.[Band],
b.[Max_Exp] AS Max_Yrs_Experience,
CASE WHEN a.Performance_Score = 0 AND (a.Status_Active > 0 OR a.Status_New > 0)
THEN CONVERT(varchar, 0)
WHEN a.Performance_Score > 0
THEN [Performance_Score]
ELSE 'No History Data Found'
END AS Performance_Score
INTO #EXPER
FROM #PERFORMANCE a, #agg_exp b
WHERE a.[Emp_No] = b.[Emp_No]
ORDER BY Performance_Score DESC
Error converting varchar to float.
I don't know why I am getting this error.
The difficulty you are having is due to that SQL Server requires that all posssible values generated in a CASE expression have the same type. Since your ELSE uses text, which can't be converted to any numeric type, the only option is to convert the numbers to text.
CASE WHEN a.Performance_Score = 0 AND (a.Status_Active > 0 OR a.Status_New > 0)
THEN CONVERT (VARCHAR(10), 0) -- zero as text
WHEN a.Performance_Score > 0
THEN CONVERT (VARCHAR(10), [Performance_Score]) -- performance score as text
ELSE 'No History Data Found' -- this is already text
END AS Performance_Score
Going by the error message, I am assuming here that [Performance Score] is a float column. If it be some other type, you would have to modify the call to CONVERT() appropriately.

How to round this result in SQL SELECT statement

I need a method to round the result returned from the following statement:
CASE
WHEN 0 <> (sod.XDFFLT - sod.DUEQTY)
THEN (sod.XDFFLT - sod.DUEQTY)
ELSE ''
END AS Balance
Which resides in this SELECT statement.
SELECT TOP (10000) som.ORDNUM
,som.NAME
,som.ADDR1
,som.ADDR2
,som.CITY
,som.STATE
,som.ZIPCD
,som.CNTRY
,som.CUSTPO
,COALESCE(cpd.CUSTPRT, sod.PRTNUM) AS CustomerSku
,cpd.CUSTPRT
,som.CUSTID
,sod.PRTNUM
,ps.PMDES1
,sod.CURQTY
,sod.DUEQTY
,sod.XDFFLT
,sod.SHPQTY
,CASE
WHEN 0 <> (sod.XDFFLT - sod.DUEQTY)
THEN (sod.XDFFLT - sod.DUEQTY)
ELSE ''
END AS Balance
,sod.LINNUM + sod.DELNUM AS LineDelNum
,CASE
WHEN 12 <= len(sod.UDFREF)
THEN substring(sod.UDFREF, 9, 4)
ELSE sod.UDFREF
END AS Skid
Replace the CASE with this:
,CASE
WHEN 0 <> (sod.XDFFLT - sod.DUEQTY)
THEN ROUND((sod.XDFFLT - sod.DUEQTY), <number_of_decimals>)
ELSE NULL
END AS Balance
Make sure to replace the <number_of_decimlas> with the appropriate number of decimals you want the number to be rounded to.
greater than 0 will return a number which is rounded on the right side of the comma (decimal point)
less than 0 will return a number which is rounded on the left side of the comma (decimal point)
Also, don't use a blank string in the ELSE clause of your case since this will cause a datatype missmatch and generate an error (a CASE must return a single datatype). Hence, it is better to replace this with NULL, since your first condition will always return a number.

SQL Server : ignore strings in SUM function

I do a sum function over a column. But the column can have string values also. I want SQL Server to ignore the string values and sum only the string values.
Eg: column can have values like 16000Euro or 2588, or 3671.
The input is from user and I cant change validation in the app to integer
I have tried this but still shows error:
SUM(CASE WHEN Type_New = 202 AND ISNUMERIC(Summe) = 1
THEN Summe
ELSE 0
END) AS total_Euro
So how can I ignore the string values when doing sum operation?
The error I get is:
Error converting nvarchar value '2588. 'in the int data type.
EDIT: I want SQL to ignore such string values and sum what it can.. The main aim is that Query should not throw any error
Try the below Query, it will work perfectly :)
SELECT SUM(CASE WHEN Type_New = 202 AND ISNUMERIC(Summe + '.0e0') = 1
THEN Summe
ELSE 0
END) AS total_Euro FROM TableName
IsNumeric returns 1 if the varchar value can be converted to ANY number type (includes int, bigint, decimal, numeric, real & float) Values like 1e4,1., 2.0 will create the issue if the above check to bypass these values is not added.
You should not name column same as a keyword in SQL Server , if this cannot be avoided you can escape column name by enclosing in square bracketes [Sum] as shown below
SELECT SUM(CASE WHEN Type = 202 AND ISNUMERIC([Sum]) = 1 THEN [Sum] ELSE 0 END) AS total_Euro
Try this
SUM(CASE WHEN Type = 202 AND case when Sum not like '%[^0-9]%' THEN Sum END ELSE 0 END) AS total_Euro
or
SUM(CASE WHEN Type = 202 AND ISNUMERIC(Sum+'.e0') = 1 THEN Sum ELSE 0 END) AS total_Euro
Try this:
SUM (CASE
WHEN Type_New = 202 AND ISNUMERIC(Summe) = 1 THEN CAST(summe AS DECIMAL(9,2))
ELSE 0 END) AS TotalEuro
I don't know if you do this SUM for one column or what, but also you can filter out what you need and then sum:
SELECT SUM(Summe) AS total_Euro
FROM someTable
WHERE Type_New = 202 AND ISNUMERIC(Summe) = 1
ISNUMERIC function considers strings that contain large numeric (e.g., 9223372036854775808), decimals (e.g., 12.4), currency figures (e.g., $123), and floating-point values (e.g., 1E2) to be strings that can be converted to a numeric data type.
Now to calculate Sum you will have to convert string to an integer[ this assumption is based on
sample data you have posted] but fact is string can be numeric but might not be convertible to an integer; the ISNUMERIC function is limited in the sense that it can tell you only whether the string can be converted to any numeric data type.
So if your column doesn't have string data like 1E3 or 12.4 or $123 which are numeric but not integers you can simply cast the target column to int as below and calculate the sum :
select SUM(CASE WHEN Type_New = 202 AND ISNUMERIC(Summe) = 1
THEN CAST(Summe AS INT)
ELSE 0
END) AS total_Euro
FROM test
else you shoudl go for a more generic function which as discussed here..
http://sqlmag.com/t-sql/can-i-convert-string-integer