Oracle SQL: Replace all non-numeric values, such as NULL, blank or empty strings - sql

I have a column that is formatted as number but seems to contain some other values as well that are causing trouble with my other functions (Rtrim, Xmlagg, Xmlelement, Extract), leading the whole query to fail (which works well if I take this column out).
Can someone tell me the best way to replace anything in a column that is not a valid number by 0 (or alternatively a placeholder number like 99999) ?
I tried the following but guess this only covers NULL values, not empty strings or blank strings which I think I have to replace first.
TO_CHAR(NVL(a.mycolumn, 0))
Many thanks in advance,
Mike

In Oracle, you should be able to use TRIM():
NVL(TRIM(a.mycolumn), '0')
Oracle (by default) treats empty strings as NULL.
Do note that this will trim the result, even if it is not NULL. If that is not desirable, use CASE:
(CASE WHEN TRIM(a.mycolumn) IS NULL THEN '0' ELSE a.myolumn END)

Use REGEXP_LIKE
For Numeric:
REGEXP_LIKE (numeric_value, '^\d+(\.\d+)?$')
or with null
REGEXP_LIKE(NVL(value, 'NULL'), '^\d+(\.\d+)?$|NULL$')

Related

LTRIM(RTRIM(COLUMN)) in sql server

I need to create a query to collect all the rows with column A not null and not blank.
When I used this:
AND A.EXP_GRAD_TERM is not null AND A.EXP_GRAD_TERM <> ' '
I got 1169 records which all have some values for the field.
But when I used this:
AND LTRIM(RTRIM(A.EXP_GRAD_TERM)) is not null
I got 1932 records. They have the rows with values and rows with blanks. I even convert the column, the column only has blanks or the values, not other weird invisible character.
I do not know why. I thought they should have worked the same way.
Any thoughts?
This expression:
LTRIM(RTRIM(A.EXP_GRAD_TERM)) is not null
is exactly equivalent to:
A.EXP_GRAD_TERM is not null
An empty string is different from NULL, so removing spaces -- even from a string that only has spaces -- has no effect on the NULL comparison.
If you are confused, perhaps you have experience with Oracle where empty strings and NULL are the same thing. That is a peculiar property of Oracle.
LTRIM() function:
Returns a character expression after it removes leading blanks.
RTRIM() function:
Returns a character string after truncating all trailing spaces.
They are different from IsNull or empty string condition (CASE WHEN IS NULL OR <>'')
References
LTRIM (Transact-SQL)
RTRIM (Transact-SQL)
Combine COALESCE() with LTRIM() and RTRIM():
AND RTRIM(LTRIM(COALESCE(A.EXP_GRAD_TERM, ''))) <> ''
COALESCE(A.EXP_GRAD_TERM, '') will return '' for every null value.
see if you want to get the values that are not null and not empty you can use isnull (exp, replace_value)
AND RTRIM(LTRIM(ISNULL(A.EXP_GRAD_TERM, ''))) <> ''
isnull isnull replaces a null value for which you want to replace it. you could also use COALESCE which "returns the first non-null expression among your arguments"
One apparent advantage that COALESCE has over ISNULL is that it supports more than two inputs, whereas ISNULL supports only two. Another advantage of COALESCE is that it's a standard function (namely, defined by the ISO/ANSI SQL standards), whereas ISNULL is T-SQL–specific. These differences between the two functions are fairly straightforward.
if you want more information about the differences between ISNULL and COALESCE you can see it on this link

Teradata: Error 2621 while converting the value - how to find bad characters?

I need to convert varchar value into NUMERIC and receive below error.
Error 2621: Bad characters in format or data of (variable_name)
I want to remove the rows with those bad characters and keep only convertable ones.
How to do that in Teradata? Does Teradata have some function to do that? (something like PRXMATCH in SAS)
Thanks
Simply apply TO_NUMBER which returns NULL for bad data points:
TO_NUMBER(mycol)
If you don't use regular expressions, you can use translate. In Oracle, I would write this as:
select col
from t
where translate(col, 'x0123456789.', 'x') is not null and
col not like '%.%.%';
I think Teradata has a more sensible policy on empty strings, so it would look like:
select col
from t
where otranslate(col, '0123456789.', '') <> '' and
col not like '%.%.%';
Of course, remove the . if you only want integers.

Sybase to Teradata inquiry LIKE '[0-9]'

CASE
WHEN <in_data> LIKE '[0-9][0-9][0-9][0-9][0-9][0-9]' THEN SUBSTR(<in_data>,1,3)
ELSE '000'
END
We're doing a migration project from Sybase to Teradata, and having a problem figuring this one out :) I'm still new to Teradata.
I would like to ask the equivalent TD code for this -
LIKE '[0-9][0-9][0-9][0-9][0-9][0-9]' to Teradata
Basically, it just checks whether the digits are numeric value.
Can someone give me a hint on this
You can also use REGEXP_SUBSTR to directly extract the three digits:
COALESCE(REGEXP_SUBSTR(in_data,'^[0-9]{3}(?=[0-9]{3}$)'), '000')
This looks for the first three digits and then does a lookahead for three following digits without adding them to the overall match.
^ indicates the begin of the string, '$' the end, so there are no other characters before or after the six digits. (?=...) is a so-called "lookahead", i.e. those three digits are checked, but ignored.
If there's no match the regex returns NULL which is changed to '000'.
You need to use regexp instead of like, since [0-9][0-9][0-9][0-9][0-9][0-9] is a regular expression.
To do an exact match, you need to add anchors. ie, to match the string which contains an exact 6 digit chars.
regexp '^[0-9]{6}$'
or
regexp '^[[:digit:]]{6}$'

How to make to_number ignore non-numerical values

Column xy of type 'nvarchar2(40)' in table ABC.
Column consists mainly of numerical Strings
how can I make a
select to_number(trim(xy)) from ABC
query, that ignores non-numerical strings?
In general in relational databases, the order of evaluation is not defined, so it is possible that the select functions are called before the where clause filters the data. I know this is the case in SQL Server. Here is a post that suggests that the same can happen in Oracle.
The case statement, however, does cascade, so it is evaluated in order. For that reason, I prefer:
select (case when NOT regexp_like(xy,'[^[:digit:]]') then to_number(xy)
end)
from ABC;
This will return NULL for values that are not numbers.
You could use regexp_like to find out if it is a number (with/without plus/minus sign, decimal separator followed by at least one digit, thousand separators in the correct places if any) and use it like this:
SELECT TO_NUMBER( CASE WHEN regexp_like(xy,'.....') THEN xy ELSE NULL END )
FROM ABC;
However, as the built-in function TO_NUMBER is not able to deal with all numbers (it fails at least when a number contains thousand separators), I would suggest to write a PL/SQL function TO_NUMBER_OR_DEFAULT(numberstring, defaultnumber) to do what you want.
EDIT: You may want to read my answer on using regexp_like to determine if a string contains a number here: https://stackoverflow.com/a/21235443/2270762.
You can add WHERE
SELECT TO_NUMBER(TRIM(xy)) FROM ABC WHERE REGEXP_INSTR(email, '[A-Za-z]') = 0
The WHERE is ignoring columns with letters. See the documentation

SQL String contains ONLY

I have a table with a field that denotes whether the data in that row is valid or not. This field contains a string of undetermined length. I need a query that will only pull out rows where all the characters in this field are N. Some possible examples of this field.
NNNNNNNNNNNNNNNNNNN
NNNNNNNNNNNNNNNNNNNNNNN
NNNNNEEEENNNNNNNNNNNN
NNNNNOOOOOEEEENNNNNNNNNNNN
Any suggestions on a postcard please.
Many thanks
This should do the trick:
SELECT Field
FROM YourTable
WHERE Field NOT LIKE '%[^N]%' AND Field <> ''
What it's doing is a wildcard search, broken down:
The LIKE will find records where the field contains characters other than N in the field. So, we apply a NOT to that as we're only interested in records that do not contain characters other than N. Plus a condition to filter out blank values.
SELECT *
FROM mytable
WHERE field NOT LIKE '%[^N]%'
I don't know which SQL dialect you are using. For example Oracle has several functions you may use. With oracle you could use condition like :
WHERE LTRIM(field, 'N') = ''
The idea is to trim out all N's and see if the result is empty string. If you don't have LTRIM, check if you have some kind of TRANSLATE or REPLACE function to do the same thing.
Another way to do it could be to pick length of your field and then construct comparator value by padding empty string with N. Perhaps something like:
WHERE field = RPAD('', field, 'N)
Oracle pads that empty string with N's and picks number of pad characters from length of the second argument. Perhaps this works too:
WHERE field = RPAD('', LENGTH(field), 'N)
I haven't tested those, but hopefully that give you some ideas how to solve your problem. I guess that many of these solutions have bad performance if you have lot of rows and you don't have other WHERE conditions to select proper index.