Sqlserver Error on Inner join with overflow Field - sql

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)

Related

Join tables query failed with error code- Conversion failed when converting the varchar value 'XYZ' to data type tinyint

I'm facing an issue while trying to join two tables.I have checked the data types are same at both the tables still the error related to data types conversion is shown. Error details are below:
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'A00.0' to data type tinyint.
Join query that I used is as below:
SELECT table1.column1,table1.column2,table2.column1
FROM table1
LEFT JOIN table2
ON table1.matching_column = table2.matching_column;
Can anyone help me?
You have two column of different data type .. one is a string and one is a int
the join (impilcitally ) convert a string in a INT but this fails
if you can't change the data struct for adding same data type to the involved columns .. try convert int to string
SELECT table1.column1,table1.column2,table2.column1
FROM table1
LEFT JOIN table2
ON table1.matching_column = cast(table2.matching_column,as varchar(32) ) ;
or
SELECT table1.column1,table1.column2,table2.column1
FROM table1
LEFT JOIN table2
ON cast(table1.matching_column,as varchar(32) ) = table2.matching_column ;
Clearly, you are matching two columns that do not have the same type. You should fix the types!
In this case, I recommend converting to numbers, rather than strings. This is because I have been bitten by leading zeros in the past -- the strings are not the same but the numbers are.
In SQL Server, use try_cast():
SELECT table1.column1, table1.column2, table2.column1
FROM table1 LEFT JOIN
table2
ON table1.matching_column = try_cast(table2.matching_column as tinyint);
Of course, this assumes that table2 has the string column.

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

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) )

Best Way to do a JOIN on Product UPC varchar(20)?

I am trying to do a JOIN on two Tables. Each table contains a UPC varchar2(20) from different data sources.
What makes this JOIN a bit difficult is that the values of UPC can vary in size, can sometimes be padded with leading zeros, and sometimes not. All contain a trailing check digit.
For example:
Table 1 Table 2
UPC "00000123456789" "123456789"
"234567890" "234567890"
"00000003456789" "00000003456789"
"3456799" "00000003456799"
My thoughts are to convert each to a long and then do the compare. Or I can append leading zeros. Or an do a contains.
What is the best way to do the join using SQL?
You can try this:
select * from
table1 inner join table2
on (CAST(CAST(table1.UPC AS BIGINT) AS VARCHAR))
=(CAST(CAST(table2.UPC AS BIGINT) AS VARCHAR))
SQL FIDDLE DEMO
or
select * from
table1 inner join table2
on (RIGHT(table1.UPC,(LEN(table1.UPC) - PATINDEX('%[^0]%',table1.UPC)) + 1))
=(RIGHT(table2.UPC,(LEN(table2.UPC) - PATINDEX('%[^0]%',table2.UPC)) + 1))
SQL FIDDLE DEMO
This is not the highest-performance option, but it is the simplest:
SELECT
T1.UPC,
T2.Column1
FROM
myTable T1
INNER JOIN myTable T2 ON
RIGHT(REPLICATE('0', 20) + T2.UPC, 20) = RIGHT(REPLICATE('0', 20) + T1.UPC, 20)
Alternatively, you can create computed columns for these padded UPCs, and place indexes upon them. However, this comes with a slew of restrictions. I have not been able to use this in the real world very many times.
Indexes on Computed Columns (MSFT)
If you have the ability to add columns to your table, you could have persisted computed columns to just cast your varchar to bigint. Then they can be indexed and the joins on these would be a lot quicker. In apps where there are way more reads than writes, this can be worthwhile.
create table ack
(
UPC
varchar( 20 ) null,
UPCValue
as isnull( convert( bigint, Upc ), 0 ) persisted
)
You don't have to do the isnull if Upc doesn't need to support null.
Most UPC values are 12 digits, or 13 for the EAN variety (see http://en.m.wikipedia.org/wiki/Universal_Product_Code). So if you can get away with altering your tables to make the column size match the expected value size that would be the simplest way. You could alter the tables to be varchar(18) to allow for 5-6 leading zeros, while still allowing the values to safely be cast to bigint. The maximum size of bigint is 9,223,372,036,854,775,807 (19 digits), so any numeric value stored in varchar(18) will fit. Then you can query easily:
Select *
From tab1
Join tab2
on cast (tab1.upc as bigint) = cast(tab2.upc as bigint);
If you're stuck with varchar(20) columns, casting to bigint will still work assuming your actual data doesn't contain erroneous values that exceed the maximum size of bigint. But obviously that isn't bulletproof. A string of twenty nines ('99999999999999999999'), for example, will result in data truncation.
If you really need 20 digits you'll need to compare the strings by left-padding with zeros or trimming off the left zeros, as shown in some of the other answers.

How to convert varchar column values into int?

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