Case when statement SQL - 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.

Related

How to check for null/empty/whitespace values with a single test in PostgreSQL

I would like to check an input (parameter) of a stored procedure if it has many spaces and empty, not just 1 space like so:
' ' '.
I tried :
IF column IS NULL or TRIM(column IS NULL) THEN RAICE NOTICE 'input is empty spaces';
END IF;
But the spaces input still passes through.
You could use COALESCE() here:
IF
COALESCE(column, '') ~ '^\s*$'
THEN
RAICE NOTICE 'input is empty spaces';
END IF;
The pattern ^\s*$ will match zero or more whitespace characters. The outer call to COALESCE() replaces NULL column values with empty string, which will match the regex pattern.
TRIM(column IS NULL) should result in an error, because column is null yields a boolean and trim() doesn't work on boolean values.
Note that trim() will return an empty string if the input is only blank, not null (an empty string '' is something different than null)
You can shorten the whole test to a single expression:
if nullif(trim(column), '') is null then ...

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

DB2 TRIM 000000 to 0

I have looked at:
DB2 SQL Query Trim inside trim
Trimming Blank Spaces in Char Column in DB2
SQL Trim after final semi colon
The IBM infocenter.
I have a column that is six long and a character column. A typical value would be AA01AA. I need to substring the middle 2 characters out of the value and convert to a number.
I am doing this with the following code: TRIM(L '0' FROM(SUBSTRING(Myfield, 3, 2))). In the example value above that gives me 1. The problem comes in when the value is 000000. The trim returns ''. I need it to return 0.
I have tried REPLACE(TRIM(L '0' FROM(SUBSTRING(Myfield, 3, 2))),'' ,'0') but that simply gives me a blank string back. I have also tried TRANSLATE(TRIM(L '0' FROM(SUBSTRING(Myfield, 3, 2))), '0', '') but that gives an error about parameter 03 being an invalid data type, length etc.
I would appreciate any help.
Something like this should do the trick:
integer(substr(myField,3,2)))
The SUBSTR extracts the two characters, the INTEGER takes it as input and converts it to a number. TRIM is not necessary at all.
values(integer(substr('000000',3,2)))
1
-----------
0
1 record(s) selected.

Regex to split values in PostgreSQL

I have a list of values coming from a PGSQL database that looks something like this:
198
199
1S
2
20
997
998
999
C1
C10
A
I'm looking to parse this field a bit into individual components, which I assume would take two regexp_replace function uses in my SQL. Essentially, any non-numeric character that appears before numeric ones needs to be returned for one column, and the other column would show all non-numeric characters appearing AFTER numeric ones.
The above list would then be split into this layout as the result from PG:
I have created a function that strips out the non-numeric characters (the last column) and casts it as an Integer, but I can't figure out the regex to return the string values prior to the number, or those found after the number.
All I could come up with so far, with my next to non-existant regex knowledge, was this: regexp_replace(fieldname, '[^A-Z]+', '', 'g'), which just strips out anything not A-Z, but I can;t get to to work with strings before numeric values, or after them.
For extracting the characters before the digits:
regexp_replace(fieldname, '\d.*$', '')
For extracting the characters after the digits:
regexp_replace(fieldname, '^([^\d]*\d*)', '')
Note that:
if there are no digits, the first will return the original value and then second an empty string. This way you are sure that the concatenation is equal to the original value in this case also.
the concatenation of the three parts will not return the original if there are non-numerical characters surrounded by digits: those will be lost.
This also works for any non-alphanumeric characters like #, [, ! ...etc.
Final SQL
select
fieldname as original,
regexp_replace(fieldname, '\d.*$', '') as before_s,
regexp_replace(fieldname, '^([^\d]*\d*)', '') as after_s,
cast(nullif(regexp_replace(fieldname, '[^\d]', '', 'g'), '') as integer) as number
from mytable;
See fiddle.
This answer relies on information you delivered, which is
Essentially, any non-numeric character that appears before numeric
ones needs to be returned for one column, and the other column would
show all non-numeric characters appearing AFTER numeric ones.
Everything non-numeric before a numeric value into 1 column
Everything non-numeric after a numeric value into 2 column
So there's assumption that you have a value that has a numeric value in it.
select
val,
regexp_matches(val,'([a-zA-Z]*)\d+') AS before_numeric,
regexp_matches(val,'\d+([a-zA-Z]*)') AS after_numeric
from
val;
Attached SQLFiddle for a preview.

Regular expression to validate whether the data contains numeric ( or empty is also valid)

i have to validate the data contains numeric or not and if it is not numeric return 0 and if it is numeric or empty return 1.
Below is my query i tried in SQL.
SELECT dbo.Regex('^[0-9]','123') -- This is returning 1.
SELECT dbo.Regex('^[0-9]','') -- this is not returning 1 but i want to return as 1 and i try to put space in "pattern" also it is not working...
please can any one help....
Thanks in advance
Try:
SELECT dbo.Regex('^[0-9]*$','123')
or better yet:
SELECT dbo.Regex('^\d*$','123')
\d is standard shorthand for [0-9]. Note that when you use [0-9] it means "match exactly one digit. The * wildcard means match zero or more so \d* means match zero or more digits, which includes an empty result.
Your Regex is not quite right: "^[0-9]" checks only, if the first character in the string is a number. Your regex would return 1 on "3abcde".
Use
"^\d*$"
to check if the field contains only numbers (or nothing). If you want to allow whitespace, use
"^\s*\d*\s*$"
If you want to allow signs and decimals, try
"^\s*(+|-)?\d*\.?\d*\s*$"
Try ^[0-9]*$, which will match 0 or more digits only:
SELECT dbo.Regex('^[0-9]*$','')
should return 1, as should...
SELECT dbo.Regex('^[0-9]*$','123')