How to convert varchar column values into int? - sql

I have a column toysid which is of varchar datatype in one table. Also another table having same the column toysid with int datatype (I know I can modify column for first table but I have to follow some procedure to keep it as varchar).
I have written following query to join the table:
select study.toysid
from study
join concepts on study.toysid = concepts.toysid
The query returns error:
Conversion failed wher converting varchar datatype into int
Hence I have tried below query:
select study.toysid
from study
join concepts on convert(int, study.toysid) = concepts.toysid
I got the same error. How to convert it? I have searched in many websites but I'm unable to get solution. Please anyone help on this.

Make sure you dont have anything other than numbers in your toysid column. I suspect there are characters other than numbers in that column. once you are sure, try the below query..
select study.toysid
from study join concepts
on cast(study.toysid as int) = concepts.toysid
or
select study.toysid
from study join concepts
on cast(study.toysid as varchar(100)) = cast(concepts.toysid as varchar(100))

You can omit such records which having non-numeric value and then cast with integer like below:
select Mystudy.toysid
from concepts
join (Select study.toysid From study WHERe ISNUMERIC(study.toysid)= 1) As MyStudy
on convert(int, MyStudy.toysid) = concepts.toysid

Related

Error converting nvarchar to bigint in WHERE clause fails but works in SELECT

I am trying to achieve the following:
Get all Field values where the FieldValue is greater than 100 when the
value is stored as a number.
The indicator of whether or not if a value was stored as a number is given by the field type, which is another where clause.
The issue I am facing is that when I try to do the data field conversion in my WHERE statement, it failed.
I run:
SELECT FieldValue FROM CARData A
JOIN Fields B ON A.FieldId = B.FieldId
WHERE FieldTypeId = 3 AND FieldValue IS NOT NULL
And this returns the expected result of:
But if I added the WHERE clause to filter by the value:
SELECT FieldValue FROM CARData A
JOIN Fields B ON A.FieldId = B.FieldId
WHERE FieldTypeId = 3 AND FieldValue IS NOT NULL
AND CAST(FieldValue AS BIGINT) > 100
It throws the error:
Error converting data type nvarchar to bigint.
I somewhat understand what the issue is- it is trying to convert ALL values in the table to a bigint and is failing when it hits a non-numeric value.
I attempted to solve this by nesting the first query in a second like so:
SELECT RESULT.FieldValue FROM (
SELECT FieldValue FROM CARData A
JOIn Fields B ON A.FieldId = B.FieldId
WHERE
FieldTypeId = 3
AND FieldValue IS NOT NULL
AND ISNUMERIC(A.FieldValue) = 1) RESULT
WHERE CAST(FieldValue AS BIGINT) > 100
But even that does not return anything other than the aforementioned error.
While it's true that changing the structure of your query can cause SQL to pick a different plan, you should limit that technique to trying to help the optimizer pick a performant plan. The reason for this is that if successful execution of the logic depends on a particular choice of plan, then your query might work today but fail tomorrow (or in production) when SQL decides to pick a different plan.
Fortunately you don't have to rely on that here! Use try_cast
SELECT FieldValue FROM CARData A
JOIN Fields B ON A.FieldId = B.FieldId
WHERE FieldTypeId = 3
AND TRY_CAST(FieldValue AS BIGINT) > 100
I'm also curious... is this part of a SQL course? If so, tell your instructor to come visit StackOverflow so we can tell them to stop teaching students to use EAV's. Unless the whole point is to show you how horrible they are! :)

Issue with Postgres not recognizing CAST on join

I'm trying to join two tables together based on an ID column. The join is not working successfully because I cannot join a varchar column on an integer column, despite using cast().
In the first table, the ID column is character varying, in the format of: XYZA-123456.
In the second table, the ID column is simply the number: 123456.
-- TABLE 1
create table fake_receivers(id varchar(11));
insert into fake_receivers(id) values
('VR2W-110528'),
('VR2W-113640'),
('VR4W-113640'),
('VR4W-110528'),
('VR2W-110154'),
('VMT2-127942'),
('VR2W-113640'),
('V16X-110528'),
('VR2W-110154'),
('VR2W-110528');
-- TABLE 2
create table fake_stations(receiver_sn integer, station varchar);
insert into fake_stations values
('110528', 'Baff01-01'),
('113640', 'Baff02-02'),
('110154', 'Baff03-01'),
('127942', 'Baff05-01');
My solution is to split the string at the dash, take the number after the dash, and cast it as an integer, so that I may perform the join:
select cast(split_part(id, '-', 2) as integer) from fake_receivers; -- this works fine, seemingly selects integers
However, when I actually attempt to perform the join, I'm getting the following error, despite using an explicit cast:
select cast(split_part(id, '-', 2) as integer), station
from fake_receivers
inner join fake_locations
on split_part = fake_locations.receiver_sn -- not recognizing split_part cast as integer!
>ERROR: operator does not exist: character varying = integer
>Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Strangely enough, I can perform this join with my full dataset (a queried result set shows up) but I then can't manipulate it at all (e.g. sorting, filtering it) - I get an error saying ERROR: invalid input syntax for integer: "UWM". The string "UWM" appears nowhere in my dataset or in my code, but I strongly suspect it has to do with the split_part cast from varchar to integer going wrong somewhere.
-- Misc. info
select version();
>PostgreSQL 10.5 on x86_64-apple-darwin16.7.0, compiled by Apple LLVM version 9.0.0 (clang-900.0.39.2), 64-bit
EDIT: dbfiddle exhibiting behavior
You need to include your current logic directly in the join condition:
select *
from fake_receivers r
inner join fake_stations s
on split_part(r.id, '-', 2)::int = s.receiver_sn;
Demo

Sqlserver Error on Inner join with overflow Field

I've been trying to run this simple query but I'm having this error:
Select I.RecipeId,
I.Name
from Ingredient as I
inner join
Recipe as R
on
I.RecipeId = CAST( R.id AS nvarchar(MAX))
where
I.RecipeId >= 241956
AND
I.RecipeId <= 242018
The conversion of the varchar value '160088961736173116 ' overflowed an int column.
You have a fundamental problem in your data model. In therecipe table, the id is bigint. In the ingredient column, the type is varchar(30).
Fix the data model! The referring types should be the same type. This is a very important principle when using relational databases. The columns that represent relationships need to be compatible.
I would start with:
alter table ingredient alter column recipeId bigint;
If this doesn't work due to a conversion error, then you need to find the offending value. You can try:
select *
from ingredient
where recipeId like '%[^0-9]%';
This should find the offending values.
RecipeID is a literal value that's being compared against a hard-coded integer 241956. This forces the motor to convert all values stored in RecipeID to an integer value. Since there's at least one value (160088961736173116) that exceeds the max value for an integer, it fails.
You can explicitly convert your hard-coded value to a BIGINT which can hold higher values, including 160088961736173116. Try this out:
Select
I.RecipeId,
I.Name
from
Ingredient as I
inner join Recipe as R on CONVERT(BIGINT, I.RecipeId) = R.id
where
I.RecipeId BETWEEN CONVERT(BIGINT, 241956) AND CONVERT(BIGINT, 242018)

Conversion failed when converting the varchar value 'T70001' to data type int?

I am receiving the above error when using the below query
SELECT b.*,E.SSNO
FROM [SRV-RVS].[dbo].[CARD] b
INNER JOIN [SRV-RVS].dbo.EMP e
on b.EMPID=E.SSNO
WHERE E.SSNO LIKE 't%'
I am trying to join both tables, here my EMPID is same as SSNO but it got a character in the begining .
Hope you got it
Regards
You could convert EMPID to a varchar and add a 'T' character in the join clause.
SELECT b.*,E.SNO
FROM [SRV-RVS].[dbo].[CARD] b INNER JOIN [SRV-RVS].dbo.EMP e ON ('T' + REPLACE(STR(CAST(b.EMPID as varchar(9)), 9), SPACE(1), '0')) = E.SSNO
WHERE E.SNO LIKE 't%'
Additional notes
I guessed on the length of the varchar but SSN is generally always 9 digits. If you are storing mask/space characters like - in your SSNO column this code will not work.
There is code in there to left 0 pad the id for SSN numbers that start with 0 as an int to string will not automatically pad 0.
If there data sets are large this could cause performance problems.
Really the schema should never have converted SSN to an int (numeric) to begin with. It should have stayed as a varchar field and ideally not set as a primary key on another table either.
Again (continue from last bullet), change the schema or add a computed column. This is currently a poor design.
Fix your table so you can do the join. The rest of this answer assumes you are using SQL Server (based on the syntax of the code in the question).
I would encourage you to do:
alter table emp
add column ssno as ( cast(stuff(empid, 1, 1, '') as int) );
Or to whatever type matches. You can even build an index on this.
Then your code doesn't have to remember business rules about the relationship between empid and ssno.
Join on table by extracting numeric values from string, so it would match on Id Column. It should return result as long u dint have any other surprises in the rowdata. This works by eliminating character in the beginning.
SELECT b.*,E.SSNO
FROM [SRV-RVS].[dbo].[CARD] b
INNER JOIN [SRV-RVS].dbo.EMP e
on right(b.EMPID, len(b.EMPID) - (PatIndex('%[0-9]%', b.EMPID )-1) )
=right(E.SSNO, len(E.SSNO) - (PatIndex('%[0-9]%', E.SSNO )-1) )

Check if field is numeric, then execute comparison on only those field in one statement?

This may be simple, but I am no SQL whiz so I am getting lost. I understand that sql takes your query and executes it in a certain order, which I believe is why this query does not work:
select * from purchaseorders
where IsNumeric(purchase_order_number) = 1
and cast(purchase_order_number as int) >= 7
MOST of the purchar_order_number fields are numeric, but we introduce alphanumeric ones recently. The data I am trying to get is to see if '7' is greater than the highest numeric purchase_order_number.
The Numeric() function filters out the alphanumeric fields fine, but doing the subsequent cast comparison throws this error:
Conversion failed when converting the nvarchar value '124-4356AB' to data type int.
I am not asking what the error means, that is obvious. I am asking if there is a way to accomplish what I want in a single query, preferably in the where clause due to ORM constraints.
does this work for you?
select * from purchaseorders
where (case when IsNumeric(purchase_order_number) = 1
then cast(purchase_order_number as int)
else 0 end) >= 7
You can do a select with a subselect
select * from (
select * from purchaseorders
where IsNumeric(purchase_order_number) = 1) as correct_orders
where cast(purchase_order_number as int) >= 7
try this:
select * from purchaseorders
where try_cast(purchase_order_number as int) >= 7
have to check which column has numeric values only.
Currently, in a table every field is setted with nvarchar(max) Like tableName (field1 nvarchar(max),field2 nvarchar(max),field3 nvarchar(3)) and tableName has 25lac Rows.
But on manually Check Field2 Contain the numeric Values Only... How to Check With t-sql that in the Complete Column (Field2) has numeric Value or not/null value with Longest Length in the Column!