converting varchar to Int SQL SERVER - sql

I needed help with something I am not entirely sure how to resolve.
This is my code :
SELECT DISTINCT
Nr_of_Times_Cust_No_Appears=CASE WHEN CAST(a.TV_Code AS Int)-CAST(BB_Code AS Int)=0 THEN COUNT(*) OVER (PARTITION BY BB_Code) ELSE 'Not same' END
FROM table
Basically, the above code is meant to make sure that the substraction of TV Code and BB Code is Zero(0) if not then 'Not Same'. TV Code and BB Code are both varchar that are CAST to Int. The problem lies in the ELSE ' NOT SAME'.
This is the output I get from SQL SERVER Management Studio:
Conversion failed when converting the varchar value 'Not same' to data type int.
What should I do to make it work?
UPDATE: I finally found the workaround.
CAST(COUNT(*) OVER (PARTITION BY XX) AS Varchar)..... It worked!!!!

This is happening because the output of your CASE statement is returning count() (an integer) from THEN 'Not same' (a string) from the ELSE. They need to be the same types. If you cast your count() to a string you will be fine.
SELECT DISTINCT Nr_of_Times_Cust_No_Appears=
CASE WHEN CAST(a.TV_Code AS Int)-CAST(BB_Code AS Int)=0
THEN CAST(COUNT(*) OVER (PARTITION BY BB_Code) AS VARCHAR)
ELSE 'Not same'
END
FROM table
Alternative:
SELECT DISTINCT Nr_of_Times_Cust_No_Appears=
CASE WHEN CAST(a.TV_Code AS Int)-CAST(BB_Code AS Int)=0
THEN COUNT(*) OVER (PARTITION BY BB_Code)
ELSE -1
END
FROM table
In the consuming code i.e. User Interface, if Nr_of_Times_Cust_No_Appears < 0 then show 'Not same'!

The error is simply occurring as your destination column can only have one data type.
The first part of your CASE statement is effictively setting the column type to expect an integer, so when you hit the ELSE section and try to insert Not Same, you're getting the error.
Sample:
SELECT Num
INTO #T
FROM ( SELECT '1' AS Num
UNION
SELECT '2'
) AS val
SELECT CASE WHEN Num = '1' THEN CAST(Num AS INT)
ELSE 'Not 1'
END AS OutputVal
FROM #T
DROP TABLE #T
Gives you:
Conversion failed when converting the varchar value 'Not 1' to data type int.
So you need to insert an acceptable value, which could be NULL:
Sample:
SELECT Num
INTO #T
FROM ( SELECT '1' AS Num
UNION
SELECT '2'
) AS val
SELECT CASE WHEN Num = '1' THEN CAST(Num AS INT)
ELSE NULL
END AS OutputVal
FROM #T
DROP TABLE #T

Check variable Nr_of_Times_Cust_No_Appears. It seems to be int, but you try to set it 'Not same'.

Related

Trying to do a simple Insert Into ... Select From ... getting 'Error converting data type nvarchar to numeric'

As the title states, I am trying to do a pretty simple Insert Into ... Select From ... routine. I am getting this error:
[Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Error converting data type nvarchar to numeric.
I ran the IsNumeric function on the five columns that are numeric and nothing was returned. Somehow, though, SQL Server is throwing a fit over something here... I just can't tell what the issue is.
I can convert everything to varchar, but that doesn't really solve the problem here. Is there a best practice for debugging something like this? I have Googled this and I have tried a couple different ideas, but now I am stuck.
Here is the SQL code:
INSERT INTO Price_Test2 (ID_RE_GLOBAL, ID_CUSIP,
PX_BID, PX_MID, PX_ASK, PX_CLOSE,
SPREAD, CRNCY, Provider, AsOfDate, rn)
SELECT
x.ID_RE_GLOBAL, x.ID_CUSIP,
x.PX_BID, x.PX_MID, x.PX_ASK, x.PX_CLOSE,
x.PX_SPREAD, x.CRNCY, x.Provider, x.AsOfDate,
ROW_NUMBER() OVER (PARTITION BY x.ID_RE_GLOBAL, x.AsOfDate ORDER BY x.ID_RE_GLOBAL) as rn
FROM
(SELECT DISTINCT
C_LONG.asset_id AS ID_RE_GLOBAL,
C_LONG.cusip AS ID_CUSIP,
CASE
WHEN C_LONG.bid_price LIKE ''
THEN '0'
ELSE C_LONG.bid_price
END AS PX_BID,
CASE
WHEN C_LONG.mean_price LIKE ''
THEN '0'
ELSE C_LONG.mean_price
END AS PX_MID,
CASE
WHEN C_LONG.offer_price LIKE ''
THEN '0'
ELSE C_LONG.offer_price
END AS PX_ASK,
CASE
WHEN C_LONG.closing_price LIKE ''
THEN '0'
ELSE C_LONG.closing_price
END AS PX_CLOSE,
CASE
WHEN C_LONG.bid_ask_sprd LIKE ''
THEN '0'
ELSE C_LONG.bid_ask_sprd
END AS PX_SPREAD,
C_LONG.currency_cd AS CRNCY,
'RE_C_LONG' AS Provider,
C_LONG.themonth + '/' + C_LONG.theday + '/' + C_LONG.theyear As AsOfDate
FROM
RE_C_LONG_2018 AS C_LONG
WHERE
C_LONG.asset_id IS NOT NULL
-- '0x0003f5000d1c2ec9',
-- '0x001005c706310107',
-- '0x0010051a84db01b2',
-- '0x001005c827880293')
) x
---- intermediate --
INSERT INTO Re_Price_Intermediate (ID_RE_GLOBAL,
ID_CUSIP,
PX_BID,
PX_MID,
PX_ASK,
PX_CLOSE,
SPREAD,
CRNCY,
Provider,
AsOfDate,
rn)
select *
from
(
select ID_RE_GLOBAL,
ID_CUSIP,
PX_BID,
PX_MID,
PX_ASK,
PX_CLOSE,
SPREAD,
CRNCY,
Provider,
AsOfDate,
rn = ROW_NUMBER()over(partition by ID_RE_GLOBAL, AsOfDate order by ID_RE_GLOBAL, AsOfDate)
from Price_Test2
) x
where x.rn = 1

Incorrect syntax for Order by clause with multiple columns

How to write order by clause with multiple columns in a case statement?
ORDER BY
CASE
WHEN #T='ABC' Then Val,Seq
ELSE Seq END
Also tried
ORDER BY
CASE
WHEN #T='ABC' Then Convert(int,Val)
WHEN #T='ABC' Then Convert(nvarchar,Seq)
ELSE Seq END
ORDER BY
CASE
WHEN #T='ABC' Then Val,Seq
ELSE Seq END
Also the below given code throws error:
"This statement is giving error: "Conversion failed when converting the nvarchar value 'EX-02-60' to data type int" when the Stored Procedure is executed."
Let's Create a table which has your columns
CREATE TABLE T(
Val VARCHAR(45),
Seq INT,
Sequence INT
);
INSERT INTO T VALUES
('A', 1, 2),
('C', 2, 1),
('B', 3, 3);
Now, let's look to your code and then brings the conditions:
Here is your code:
ORDER BY
CASE
WHEN #T='ABC' Then Val,Seq
ELSE Sequence END
If #T = 'ABC then order by Val and Seq AND DO NOT order by Sequence.
If #T <> 'ABC' then order Only with Sequence.
If you run this query:
--You was trying--
DECLARE #T VARCHAR(3) = 'ABC'; --wil works only when #T <> ABC
SELECT *
FROM T
ORDER BY CASE WHEN #T='ABC' THEN Seq END, --Take INT
CASE WHEN #T='ABC' THEN Val --Take Varchar
ELSE Sequence -- Take INT
END;
It will throw the following error if #T = 'ABC'
Msg 245 Level 16 State 1 Line 5
Conversion failed when converting the varchar value 'A' to data type int.
same as you get
Conversion failed when converting the nvarchar value 'EX-02-60' to data type int.
Now, here is what you want according to the conditions you provide:
--Fixes--
DECLARE #T VARCHAR(3) = '1'; --Try to change it to ABC too
SELECT *
FROM T
ORDER BY CASE WHEN #T='ABC' THEN Val END, --Take varchar
CASE WHEN #T='ABC' THEN Seq -- Take INT
ELSE Sequence -- Take INT
END;
/*
IF #T = ABC
ORDER BY Val, Seq; NOT Sequence
IF #T <> ABC
ORDER BY ONLY Sequence
*/
And here is a Live demo
I suspect what you're after is:
ORDER BY CASE #T WHEN 'ABC' THEN Val END,
CASE #T WHEN 'ABC' THEN Seq END,
[Sequence];
To elaborate on why you're attempts didn't work. Firstly:
WHERE Type = #T ORDER BY
CASE
WHEN #T='ABC' Then Val,Seq
ELSE Sequence END
A CASE is an expression that returns a scalar value. Here your WHEN tried to return 2 values. That's not allowed.
ORDER BY
CASE
WHEN #T='ABC' Then Convert(int,Val)
WHEN #T='ABC' Then Convert(nvarchar,Seq)
ELSE Seq END
As CASE is returns a scalar value it can only return one datatype. The CASE expression uses datatype precendence, and int has a higher precendence than nvarchar so Seq would be implicitly converted to an int; and I'd hazard a guess that that failed.
The Data type of the Value in the ORDER BY should always be same. Here you will get the conversion error because in the first Case the Data Type is INT and in the second one, it is Varchar. SO For More Secure way, you may use the following approach
;WITH CTE
AS
(
SELECT
RN_Val = ROW_NUMBER() OVER(ORDER BY Val),
RN_Seq = ROW_NUMBER() OVER(ORDER BY Seq),
*
FROM YourTable
)
SELECT
*
FROM CTE
ORDER BY
(
CASE #T
WHEN 'ABC' THEN RN_Val
WHEN 'XYZ' THEN RN_Seq
END
)

Error converting data type varchar to numeric. When try to compare numeric

I got a error when i am trying to execute below query. can anyone sort out this would appreciated.
DECLARE #TABLE TABLE(ID INT,CATEGORY VARCHAR(30),VALUE VARCHAR(30))
INSERT INTO #TABLE
SELECT 1,'A','5'
UNION ALL
SELECT 2,'B','6'
UNION ALL
SELECT 3,'C','VAL'
UNION ALL
SELECT 4,'D','HSD'
DECLARE #TABLE1 TABLE(ID INT,CATEGORY VARCHAR(30),VALUE VARCHAR(30))
INSERT INTO #TABLE1
SELECT 1,'A','5.0'
UNION ALL
SELECT 2,'B','6.0'
UNION ALL
SELECT 3,'C','VAL'
UNION ALL
SELECT 4,'D','HSD'
SELECT
A.ID,
A.CATEGORY,
A.VALUE
FROM #TABLE A, #TABLE1 B
WHERE
CASE ISNUMERIC(A.VALUE) WHEN 1 THEN CAST (A.VALUE AS NUMERIC)
ELSE A.VALUE END=CASE ISNUMERIC(B.VALUE) WHEN 1
THEN CAST (B.VALUE AS NUMERIC) ELSE B.VALUE END
I believe the error you are getting is being caused by that your CASE expressions in the WHERE clause have branches with different types, namely text and numeric. To fix this, you need to make all branches be the same type. Making everything numeric won't work because of the text, but we can make everything text instead.
For the case of numeric data, you don't even have the same type of data there either. To get around this, you can cast the numeric data to a common decimal format before converting back again to text:
WHERE
CASE WHEN ISNUMERIC(A.VALUE) = 1
THEN CONVERT(VARCHAR, CAST(A.VALUE AS DECIMAL(10,2)))
ELSE A.VALUE END =
CASE WHEN ISNUMERIC(B.VALUE) = 1
THEN CONVERT(VARCHAR, CAST(B.VALUE AS DECIMAL(10,2)))
ELSE B.VALUE END
The best long term solution for you would be to not mix text and numeric data in the same column. I don't know why this answer was downvoted, as it is working code which answers the original question.
Output:
Demo here:
Rextester
One Columns can only be one type..
You can't put two type "NUMERIC" and "varchar(30)" in one column...
Best way is cast to one type. Seems varchar(30) is a better choice.
SELECT
A.ID,
A.CATEGORY,
A.VALUE
FROM #TABLE A, #TABLE1 B
WHERE
ISNUMERIC(A.VALUE) = ISNUMERIC(B.VALUE)
and
CASE ISNUMERIC(A.VALUE) WHEN 1 THEN CAST(CAST(A.VALUE AS NUMERIC) as VARCHAR(30)) ELSE A.VALUE END
= CASE ISNUMERIC(B.VALUE) WHEN 1 THEN cast(CAST(B.VALUE AS NUMERIC) as VARCHAR(30)) ELSE B.VALUE END

SQL Server: Compare two columns

I have two columns in a SQL table as follow. I need to compare these two columns for mismatches but due to extra decimals i am getting false results. When i try to convert the first column it gives the error
"Error converting data type varchar to numeric."
How to solve this issue? The length of first column varies.
Column01(varchar) Column02(Decimal)
0.01 0.010000
0.255 0.255000
You have data in Column01 that cannot be casted to DECIMAL.
With SQL Server 2012+ I would use TRY_PARSE:
SELECT *
FROM your_table
WHERE Column02 = TRY_PARSE(Column01 AS DECIMAL(38,18));
LiveDemo
When value from column cannot be casted safely you get NULL.
For SQL Server 2008 you can use:
SELECT *
FROM #tab
WHERE (CASE
WHEN ISNUMERIC(Column01) = 1 THEN CAST(Column01 AS DECIMAL(38,18))
ELSE NULL
END) = Column02;
EDIT:
If you need it at column level use:
SELECT Column01, Column02,
CASE WHEN Column02 = TRY_PARSE(Column01 AS DECIMAL(38,18))
OR (Column02 IS NULL AND Column01 IS NULL)
THEN 'true'
ELSE 'false'
END AS [IsEqual]
FROM #tab;
LiveDemo2
You can do this using self join and conversion function
SELECT x.Column01, y.Column02
FROM table1 x, table1 y
WHERE x.Column02 = try_parse(y.Column01 as decimal(38,18))
Since I cannot comment, I like to thank lad2025 for showing live demo and introducing to data.stackexchange for composing queries
One other way of doing it:
create table #temp(col1 varchar(10),col2 decimal(10,6))
insert into #temp values(0.01,0.010000 ),(0.255,0.255000),(0.25,25),(0.555,10.0)
select * from #temp where REPLACE(REPLACE(col2,col1,''),0,'') = ''
select * from #temp where REPLACE(REPLACE(col2,col1,''),0,'') <> ''

SQL: How use case and cast in a query?

I want to cast VARCHAR to INT, but in my table i have some value like '???' then SQL Server launch this expcetion :
Conversion failed when converting the varchar value '????' to data type int.
Severity 16
I could convert this '???' to NULL, that's no problem, but how do that ?
I'm trying to do something like this:
INSERT INTO labbd11..movie(title, year)
SELECT movies.title,
CASE movies.mvyear IS '????' THEN NULL ELSE CAST (movies.mvyear AS INT)
FROM disciplinabd..movies
But nothing works ..
Any ideas guys ?
You might just want to solve this in general and deal with any non-int value the same way
INSERT INTO labbd11..movie(title, year)
SELECT movies.title,
CASE WHEN IsNumeric(movies.mvyear+ '.0e0') <> 1 THEN NULL
ELSE CAST (movies.mvyear AS INT) END
FROM disciplinabd..movies
See this question
I believe you would want something like
INSERT INTO labbd11..movie(title, year)
SELECT movies.title,
CAST( CASE movies.mvyear
WHEN '????' THEN NULL
ELSE movies.mvyear
END AS INT)
FROM disciplinabd..movies
You want your CASE statement to return a VARCHAR (either the MVYEAR or NULL) and then you want the CAST to operate on the result of the CASE.
INSERT INTO labbd11..movie(title, year)
SELECT movies.title,
CASE WHEN movies.mvyear = '????' THEN NULL
ELSE CAST (movies.mvyear AS INT) END
FROM disciplinabd..movies
INSERT INTO labbd11..movie(title, year)
SELECT
movies.title,
CAST(CASE WHEN movies.mvyear = '????' THEN NULL ELSE movies.mvyear END AS INT)
FROM
disciplinabd..movies
You can also use:
CAST(NULLIF(movies.mvyear,'????') AS INT)