Trying to Find Maximum Value - sql

I'm trying to find a maximum number of a string. First I try to turn it into an Integer field first, but keep getting error message for example:
Conversion failed when converting the nvarchar value '3,029' to data type int.
I tried to replace the possible single quotation marks into a blank char like below:
SELECT TOP 100 (CAST(REPLACE(a.PortNumber,'''','') AS INT)) FROM dbo.Account a
WHERE nwp_AccountType = 121710000
ORDER BY (CAST(REPLACE(a.PortNumber,'''','') AS INT)) DESC
But still getting the same error message again.
Any idea?

The error is in your REPLACE statement
(CAST(REPLACE(a.PortNumber,',','') AS INT))

The problem was the comma, I added another replace for the comma to an empty string and it works.

Related

Getting an error: Argument data type varchar is invalid for argument 2 of substring function

I'm trying to get a substring from the value of a column and I'm getting the following error Argument data type varchar is invalid for argument 2 of substring function.
The column type is NvarChar(50) and is a system column for an application, so I can't modify it.
Ideally I'd just be able to select the substring as part of the query without having to alter the table, or create a view or another table.
Here's my query
SELECT SUBSTRING(INVOICE__, ':', 1)
FROM dwsystem.dbo.DWGroup
Im trying to select only everything in the string after a specific character. In this case the : character.
Use charindex with : as the first argument
select substring(invoice__,charindex(':',invoice__)+1,len(invoice__))
from dwsystem.dbo.dwgroup
SUBSTRING parameter is start position and end position so both parameter will be number like below
SELECT SUBSTRING(INVOICE__, 1, 1)
FROM dwsystem.dbo.DWGroup
you can use SUBSTRING_INDEX as you used mysql
SELECT SUBSTRING_INDEX(INVOICE__,':',-1);
example
SELECT SUBSTRING_INDEX('mytestpage:info',':',-1); it will return
info

Invalid digits on Redshift

I'm trying to load some data from stage to relational environment and something is happening I can't figure out.
I'm trying to run the following query:
SELECT
CAST(SPLIT_PART(some_field,'_',2) AS BIGINT) cmt_par
FROM
public.some_table;
The some_field is a column that has data with two numbers joined by an underscore like this:
some_field -> 38972691802309_48937927428392
And I'm trying to get the second part.
That said, here is the error I'm getting:
[Amazon](500310) Invalid operation: Invalid digit, Value '1', Pos 0,
Type: Long
Details:
-----------------------------------------------
error: Invalid digit, Value '1', Pos 0, Type: Long
code: 1207
context:
query: 1097254
location: :0
process: query0_99 [pid=0]
-----------------------------------------------;
Execution time: 2.61s
Statement 1 of 1 finished
1 statement failed.
It's literally saying some numbers are not valid digits. I've already tried to get the exactly data which is throwing the error and it appears to be a normal field like I was expecting. It happens even if I throw out NULL fields.
I thought it would be an encoding error, but I've not found any references to solve that.
Anyone has any idea?
Thanks everybody.
I just ran into this problem and did some digging. Seems like the error Value '1' is the misleading part, and the problem is actually that these fields are just not valid as numeric.
In my case they were empty strings. I found the solution to my problem in this blogpost, which is essentially to find any fields that aren't numeric, and fill them with null before casting.
select cast(colname as integer) from
(select
case when colname ~ '^[0-9]+$' then colname
else null
end as colname
from tablename);
Bottom line: this Redshift error is completely confusing and really needs to be fixed.
When you are using a Glue job to upsert data from any data source to Redshift:
Glue will rearrange the data then copy which can cause this issue. This happened to me even after using apply-mapping.
In my case, the datatype was not an issue at all. In the source they were typecast to exactly match the fields in Redshift.
Glue was rearranging the columns by the alphabetical order of column names then copying the data into Redshift table (which will
obviously throw an error because my first column is an ID Key, not
like the other string column).
To fix the issue, I used a SQL query within Glue to run a select command with the correct order of the columns in the table..
It's weird why Glue did that even after using apply-mapping, but the work-around I used helped.
For example: source table has fields ID|EMAIL|NAME with values 1|abcd#gmail.com|abcd and target table has fields ID|EMAIL|NAME But when Glue is upserting the data, it is rearranging the data by their column names before writing. Glue is trying to write abcd#gmail.com|1|abcd in ID|EMAIL|NAME. This is throwing an error because ID is expecting a int value, EMAIL is expecting a string. I did a SQL query transform using the query "SELECT ID, EMAIL, NAME FROM data" to rearrange the columns before writing the data.
Hmmm. I would start by investigating the problem. Are there any non-digit characters?
SELECT some_field
FROM public.some_table
WHERE SPLIT_PART(some_field, '_', 2) ~ '[^0-9]';
Is the value too long for a bigint?
SELECT some_field
FROM public.some_table
WHERE LEN(SPLIT_PART(some_field, '_', 2)) > 27
If you need more than 27 digits of precision, consider a decimal rather than bigint.
If you get error message like “Invalid digit, Value ‘O’, Pos 0, Type: Integer” try executing your copy command by eliminating the header row. Use IGNOREHEADER parameter in your copy command to ignore the first line of the data file.
So the COPY command will look like below:
COPY orders FROM 's3://sourcedatainorig/order.txt' credentials 'aws_access_key_id=<your access key id>;aws_secret_access_key=<your secret key>' delimiter '\t' IGNOREHEADER 1;
For my Redshift SQL, I had to wrap my columns with Cast(col As Datatype) to make this error go away.
For example, setting my columns datatype to Char with a specific length worked:
Cast(COLUMN1 As Char(xx)) = Cast(COLUMN2 As Char(xxx))

How to select node from potentially not well-formed xml as a varchar?

I have varying 'message' columns which is a varchar that should be an xml, but some of them may not be well-formed or valid. I am trying to weed out the rows that have a given input value to a node like this:
Select * from messagelog where message like '%1234567%'
But when I filter those to try and lift another node (1234567) whos value I do not know, I come across the issue.
I've casting every entry to a xml wont work since like 1% of messages are not valid.
This code doesn't parse the varchar into xml, but returns a substring if it exists. However, I get a conversion error on the charindex = 0 case. Some MessageIds are these large varchars.
Is there anything that I'm missing here? Am I SOL for using SQL to parse not well-formed XML varchars?
select
case when CAST(charindex('<RelatesToMessageID>', message) as varchar(100)) = 0
then 1
else
substring(message, charindex('<RelatesToMessageID>', message)+20, charindex('</RelatesToMessageID>', message)-charindex('<RelatesToMessageID>', message)-20)
end
from messagelog
Conversion failed when converting the varchar value '959B91D824324108948261EC2A81CD92' to data type int.
Your CASE is returning both a VARCHAR and an INT. You should change your then 1 to then '1' so both parts of your CASE return a VARCHAR
I saw that I could select the substring only in locations where there are an existing NCPDPID. This would get rid of the case altogether.
if exists(Select * from messagelog where message like '%<NCPDPID>1234567</NCPDPID>%')
select substring(message, charindex('<MessageID>', message)+11, charindex('</MessageID>', message)-charindex('<MessageID>', message)-11) from messagelog where message like '%<NCPDPID>1234567</NCPDPID>%'

IBM DB2 for i SQL (iSeries) - Removing a character from end of a field using update

I have a product table called PDPRODP - for certain styles within this table I used a concat statement to add a full-stop to their description (PRDESC), I now wish to remove this full stop.
The descriptions are varying length, the field max size is 30 characters and I need to physically remove the full-stop rather than using a select statement to trim the full-stop.
I tried;
UPDATE PDPRODP SET PRDESC = PRDESC-1 where PRSTYLE = 1234
But I got this error:
Character in CAST argument not valid.
I also tried this following some googling;
UPDATE PDPRODP SET PRDESC=LEFT(PRDESC, LEN(PRDESC)-1)
WHERE PRCOMP = 1 AND PRSTYL = 31285
But got this error:
LEN in *LIBL type *N not found.
Use LENGTH
UPDATE PDPRODP SET PRDESC=LEFT(PRDESC, LENGTH(PRDESC)-1)
WHERE PRCOMP = 1 AND PRSTYL = 31285
The REPLACE() function can search for all occurrences of some string, and substitute another in its place. You might search for your full-stop, and replace it with a zero-length string ''. This would be handy in cases where your search string may not always be at the end.

sql convert error on view tables

SELECT logicalTime, traceValue, unitType, entName
FROM vwSimProjAgentTrace
WHERE valueType = 10
AND agentName ='AtisMesafesi'
AND ( entName = 'Hawk-1')
AND simName IN ('TipSenaryo1_0')
AND logicalTime IN (
SELECT logicalTime
FROM vwSimProjAgentTrace
WHERE valueType = 10 AND agentName ='AtisIrtifasi'
AND ( entName = 'Hawk-1')
AND simName IN ('TipSenaryo1_0')
AND CONVERT(FLOAT , traceValue) > 123
) ORDER BY simName, logicalTime
This is my sql command and table is a view table...
each time i put "convert(float...) part " i get
Msg 8114, Level 16, State 5, Line 1
Error converting data type nvarchar to float.
this error...
One (or more) of the rows has data in the traceValue field that cannot be converted to a float.
Make sure you've used the right combination of dots and commas to signal floating point values, as well as making sure you don't have pure invalid data (text for instance) in that field.
You can try this SQL to find the invalid rows, but there might be cases it won't handle:
SELECT * FROM vwSimProjAgentTrace WHERE NOT ISNUMERIC(traceValue)
You can find the documentation of ISNUMERIC here.
If you look in BoL (books online) at the convert command, you see that a nvarchar conversion to float is an implicit conversion. This means that only "float"-able values can be converted into a float. So, every numeric value (that is within the float range) can be converted. A non-numeric value can not be converted, which is quite logical.
Probably you have some non numeric values in your column. You might see them when you run your query without the convert. Look for something like comma vs dot. In a test scenario a comma instead of a dot gave me some problems.
For an example of isnumeric, look at this sqlfiddle