LTRIM(RTRIM(COLUMN)) in sql server - sql

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

Related

Case when statement SQL

I am facing some difficulties for a Datawarehouse transformation task, I have some source columns which are coming in varchar format, data contained: Blanks, -, decimal numbers such as (1234.44).
Those columns in target are declared as number.
I am trying to treat that data with this code but I keep receiving invalid number error:
CASE WHEN
LENGTH(TRIM(TRANSLATE(column78input, '-', ' '))) is null then null
WHEN column78input IS NULL THEN 0
else to_number(column78input)
END
In first when statement I am trying to check if there is - in source, it returns null when found, and if you find it then place it as null (replacing dashes with nulls in essence)
In second when statements I am trying to treat those blanks, I thought that they might cause the error
And finally in else statement I want to parse it from varchar to number to load in target table.
If someone has some kind of suggestion, please help!
Thanks
Try with
CASE
WHEN INSTR(column78input, '-') > 0 OR column78input IS NULL THEN 0
ELSE TO_NUMBER(REPLACE(column78input, ' '))
END
INSTR returns the first position of a character in a string. So if there is no dash, it would return 0. A value greater than 0 means there is at least one dash in the string.
Here are a few mistakes in your code :
A case when statement will exit when a condition is met. So you can remove the dash in the first condition and expect it to continue to process your string in the next condition. In your code if a string had a dash, the result would be null.
LENGTH function returns the number of characters in a string. It will return a null value only if the string is null. So it's easier to directly write column78input IS NULL
You current first condition is basically this : "After replacing the dash by a space and removing all the leading/trailing spaces, if the string is null then". Because you are replacing the dashes in the string, you can't check if there is an occurrence or not.

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.

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

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

Trim SQL field and use ISNULL

fairly new to SQL and having problems with trimming the data when using in an ISNULL statement
LTRIM(RTRIM(CA.CUSTNMBR)) as AccountNumber
The above gives me the account number without spaces (correct)
,ISNULL(NAN.SageAccountNo, LTRIM(RTRIM(CA.CUSTNMBR))) AS AccountNumber
I then tried to use the same principle in the above ISNULL statement but it returns the correct column but doesn't trim the data.
I think you want:
LTRIM(RTRIM(COALESCE(NAN.SageAccountNo, CA.CUSTNMBR))) as AccountNumber
This will trim either SageAccountNo or CUSTNMBR.
You just need to use LTRIM(RTRIM( outside the ISNULL:
LTRIM(RTRIM(ISNULL(NAN.SageAccountNo, CA.CUSTNMBR)))

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