Can't cut and convert a string - weird format - sql

This question is almost the same with one of my previous questions, which can be found HERE
I have a field named: pa_value which keeps varchar records
Now this field contains records like:
0,5582
0,6985
-0,1589
0,9856
-0,6589
I'm getting these results using the following code:
CAST (replace (p7.pa_value ,'%','') AS float (3,0)) as TotalMargin
What I'm trying to do is to remove everything and leave just 5 characters(or 6 if there is a -(minus) infront of the string).
It should be looking like this:
55.82
69.85
-15.89
98.56
-65.89
I tried to cast it as a float and then to convert it to integer. I also tried the floor command, which is not for my case, without any success. I'm always getting a syntax error message. I believe that there is no way to do this

SELECT p7.pa_value=CASE WHEN LEFT( p7.pa_value,1)='-' THEN '-' +
CONVERT(varchar(max),CONVERT(float,substring(p7.pa_value,4,4))/100) ELSE
CONVERT(varchar(max),CONVERT(float,substring(p7.pa_value,3,4))/100) END
FROM <table_name>
What is being done ..
Check if starting character is '-'.
If yes then extract string starting from position 4 else starting
from position 3.
The inner convert function converts string to float for division and
the outer convert changes back the resultant value back to varchar
type.

If you know there are always four digits after the comma, you could use this, though I don't believe it's perfect:
CONVERT(NUMERIC(9,2), REPLACE(REPLACE(p7.pa_value, '%', ''), ',', '')) / 100

Related

Format query to show floating decimal in Oracle SQL

I am using Oracle SQL Developer and I have a query in which one of the columns has a number value that I want to divide by 1,000,000 then display to show commas and up to 10 decimal places if the calculate value has any decimal places. I am currently using this query:
to_char(value/1000000, 'FM999,999,990.9999999999') as Millions_Value
The above format gives me commas and retains the number of decimal places I want, but it unfortunately adds a decimal point at the end of whole numbers as well.
Example:
value/1000000 = 33993
formatted value = 33,993.
what I want = 33,993
For a decimal value, I get what I want and need to keep the format
Example:
value/1000000 = 0.158739
formatted value = 0.158739
value/1000000 = 10.82
formatted value = 10.82
And ideas on how to get rid of the decimal for integers?
The easiest way is to use RTRIM, e.g.
RTRIM(to_char(value/1000000, 'FM999,999,990.9999999999'), '.') as Millions_Value
will remove any trailing periods.
EDIT
If you want to get fancy and internationalize it you need to query NLS_SESSION_PARAMETERS to get the decimal separator, use the G (group) and D (decimal) specifiers in the format string, and then trim off any trailing decimal separator characters. Or in other words:
WITH cteData AS (SELECT 123456789.123456789 AS N FROM DUAL UNION ALL
SELECT 123 FROM DUAL),
cteDecimalSeparator AS (SELECT SUBSTR(VALUE, 1, 1) AS DECIMAL_SEPARATOR
FROM NLS_SESSION_PARAMETERS
WHERE PARAMETER = 'NLS_NUMERIC_CHARACTERS')
SELECT TO_CHAR(N, 'FM999G999G990D9999999999') AS OLD_FORMAT,
RTRIM(TO_CHAR(N, 'FM999G999G990D9999999999'), s.DECIMAL_SEPARATOR) AS NEW_FORMAT
FROM cteData d
CROSS JOIN cteDecimalSeparator s
which returns
OLD_FORMAT NEW_FORMAT
123,456,789.123456789 123,456,789.123456789
123. 123
Remember: there's no kill like overkill :-)
Personally, I think it looks good with one trailing 0, so converting your format string to have a 0 after the decimal. But to answer you question, I think you just need to trim it after you convert the number like this:
SELECT TRIM(TRAILING '.' FROM TO_CHAR('345676', 'FM999G999G990D9999999999'))
FROM DUAL;

Getting everything after last '/'

I have a path like this in my TBL_Documents table:
Uploads/Documents/6093/12/695-Graco-SW_5-15-19.pdf
I need to compare it to a file being uploaded now that will look like this:
695-Graco-SW_5-15-19.pdf
I want to compare the path in my table with the uploaded file name. I tried using substring() on the first right / but I don't really get how substring is really working. For example, I tried to do this:
select substring(right(path,1),1,1) as path from TBL_DOCUMENT
but it is only giving me the very first character from the right. I expected to see everything after the last / character.
How can I do this?
I would use an approach of finding how many characters you need to use from the right. I would do this by first reversing the string and then searching for the '/'. This will tell you how many characters from the right this '/' is. I would then use this in the RIGHT function:
SQL Fiddle
MS SQL Server 2017 Schema Setup:
Query 1:
DECLARE #documentName varchar(100) = 'Uploads/Documents/6093/12/695-Graco-SW_5-15-19.pdf'
SELECT RIGHT(#documentName, CHARINDEX('/',REVERSE(#documentName))-1)
Results:
| |
|--------------------------|
| 695-Graco-SW_5-15-19.pdf |
RIGHT(path,1) means you want [1] character from the right of the path string, or 'f'.
You then wrap 'f' in a substring, asking for [1] character starting at the [1]st position of the string. Since the expression passed to substring returns 'f', your substring also returns 'f'.
You want to use a combination of charindex and reverse to handle this appropriately.
SUBSTRING(path,len(path) - charindex('/',reverse(path))). That will not parse but it should get you on the right track.
In normal speak, this returns the string, starting with the right most '/' of the path, to the end of string.

When Select replacing comma with dot is truncating values

I'm trying to convert a varchar column where decimal separator is ','.
The workaround found was replace comma to dot but SQL Server is automatically rounding it up. See below example:
2018-10-08 -8679.95 -8679,94711560794
select DATA, REPLACE([PL]*1,',','.') , PL from TB_BOOK
Please, anyone know How can a get the value with all decimals?
Your approach to replace , with . is ok.
However on top of it you need to explicitly CAST the string to a number with enough decimals (FLOAT, DECIMAL(p, s), ...).
SELECT DATA, CAST(REPLACE([PL],',','.') AS FLOAT), PL from TB_BOOK

Convert non numeric values as numeric when they are displayed as numbers

I am using ISNUMERIC to get all non numeric rows in my table - but all I get in return is the following example 1.437.230,61 or 3.511.980,00. I really dont know how to get these few rows converted to numeric! I have conveted about 2,5 mil rows without problem but I am getting about 9000 rows that are not numeric - but as displayed above they are numbers. I have tried to trim my coloumn with no luck!
You should always name the dbms you are using. Many dbms have problems converting proper numbers such as 1.437.230,61 due to the thousand separators. So isnumeric works fine here, but the conversion function doesn't.
Use a string replace function to remove the thousand separators from the string before converting. Such as:
to_number( replace(numstr, '.', '') )

sql query for alphanumeric ID in hex

I want to be able to differentiate between a string that is alphnumeric and a string that is in hex format.
My current query is:
<columnName> LIKE '?_____=' + REPLICATE('[0-9A-Fa-f]',16)
I found this method of searching for hex ID's online and I thought it was working. However after getting a significantly larger sample size I can see a high false positive rate in my results. The problem is that this gives me all the results I do want but it also gives me a bunch of results I dont care about. For example:
I want to see:
<url>.php?mains=d7ad916d1c0396ff
but i dont want to see:
<url>.php?mblID=2007012422060265
The difference between the 2 strings is that the 16 characters at the end that i want to collect are all numeric and not a hex ID. What are some ways you guys use to limit the results to hex ID only? Thanks in advnace.
UPDATE:
Juergen brought up a good point, the second number could be a hex value to. Not all hex numbers contain [a-F]. I would like to rephrase the question to state that I am looking for an ID with both letters and numbers in it, not just numbers.
The simplest way is just to add a separate clause for that restriction:
<columnName> LIKE '?_____=' + REPLICATE('[0-9A-Fa-f]',16)
AND <columnName> NOT LIKE '?_____=' + REPLICATE('[0-9]',16)
It should be fairly simple to determine if a string contains only numbers...
Setting up a test table:
CREATE TABLE #Temp (Data char(32) not null)
INSERT #Temp
values ('<url>.php?mains=d7ad916d1c0396ff')
,('<url>.php?mblID=2007012422060265 ')
Write a query:
SELECT
right(Data, 16) StringToCheck
,isnumeric(right(Data, 16)) IsNumeric
from #Temp
Get results:
StringToCheck IsNumeric
d7ad916d1c0396ff 0
2007012422060265 1
So, if the IsNumeric function returns 0, it could be a hex string.
This makes several assumptions:
The rightmost 16 characters are what you want to check
You only ever hit 16 characters. I don't know when the string would get too long to check.
A non-numeric character means hex. Any chance of "Q" or "~" being embedded in the string?