Using decode for parameter positioning cases - sql

I have a table which contains a list of 13 digit numbers.
I want to use informatica to break these numbers down and separate them based on cases.
For example, I have the number 1196804120316.
For the first case, I wish to only take the two digits after the 68. In our example, I extract the number 04 and store it in a column.
The SQL Code for it is:
CASE WHEN ODS_CI_RPT.ADMIN.REGEXP_LIKE(DEC_REGISTRN_NBR,'^(19|20)?[0-9]{2}-[0-9]{2}-[0-9]{5,6}$')
THEN
ODS_CI_RPT.ADMIN.REGEXP_REPLACE(DEC_REGISTRN_NBR,'.*-([0-9]{2})-.*','\1',1,1)
ELSE '05'
END
AS
STATE_CODE
The next case is to take the number after 19 and store it. In this case the 68.
The SQL is:
CASE WHEN ODS_CI_RPT.ADMIN.REGEXP_LIKE(DEC_REGISTRN_NBR,'^(19|20)?[0-9]{2}-[0-9]{2}-[0-9]{5,6}$') THEN
ODS_CI_RPT.ADMIN.REGEXP_REPLACE(DEC_REGISTRN_NBR,'^([0-9]{2,4})-.*','\1',1,1)
ELSE ODS_CI_RPT.ADMIN.REGEXP_REPLACE(DEC_REGISTRN_NBR,'^([0-9]{4})-.*','\1',1,1)
END
AS
D_BIRTH_YEAR,
How would I implement this using decode in informatica?

Could you try:
WITH
input(literal) AS (
SELECT '1196804120316'
)
SELECT
-- use below in PowerCenter
MONTH(TO_DATE(SUBSTR(literal,2),'YYYYMMDDHHMI'))
-- use above in PowerCenter
AS the_month
FROM input;
the_month
4
Power Center offers all functions of Oracle. So just use the formula I show above .....

My solution to this was to use SUBSTR() in an expression. After importing the source from the table, I used:
SUBSTR(COLUMN_NAME,6,2)
To tell Informatica which position of the string I wanted broken down. Once it was broken down, the expression would capture it into a variable.

Related

How to retrieve specific chars after decimal using REGEX in Oracle SQL?

I'm using RegEx in a View in Oracle 11g and I need to display certain codes that have an 'S' in the 8th position.
Using https://regexr.com/2v41h,
I was able to display these results with
REGEXP_SUBSTR(code, '\S{8}')
Y38.9X2S
Y38.9X2D
Y38.9X2A
Y38.9X1S
My issue is that I need to return only the values that have an 'S' in the last position which is the 8th position counting the decimal. What expression should I use?
Example:
Y38.9X2S
Y38.9X1S
I have tried:
REGEXP_SUBSTR(code, '\b[S]*[8]\b') AS CODE
Thank you in advance for your help.
I am thinking:
select substr(code, -8)
from t
where code like '%_______S'
If the code is always long enough, just use '%S'.
Or, as a case expression:
select (case when code like '%_______S' then substr(code, -8) end)
You will need regular expressions if code has other characters but they may not be necessary.

Checking for a Substring in [Field] within Case Statement for Oracle PL/SQL?

I'm writing an Oracle Database Conversion script to move records (roughly 1,300) from an old DB table to a more standardized setup with a main table and several child/reference/maintenance tables. One situation I'm dealing with is where (in the old setup) several records contain [Status] values such as RECYCLED under the [Location] field. I've gone through using a Case statement to get the basics as below:
WHEN RTRIM(LTRIM(Vendor_Name)) in (
'EDAC') THEN 23 END as VendorID,
CASE
WHEN RTRIM(LTRIM(LOCATION)) in (
'Auctioned') THEN 3
WHEN RTRIM(LTRIM(LOCATION)) in (
'Recycled') THEN 5
WHEN RTRIM(LTRIM(LOCATION)) in (
'To Be Recycled') THEN 6
WHEN RTRIM(LTRIM(LOCATION)) in (
'DISPOSED OF') THEN 7
WHEN RTRIM(LTRIM(LOCATION)) in (
'To Be Auctioned') THEN 4
There are however a few variations with extra text (and variations OF the extra text) such as 'To be auctioned, SERVER ROOM'. I'm trying to figure out how to do something like a CONTAINS or LIKE check within my case statement, so like in the mentioned CONTAINS ('%To be auctioned%') THEN 42.
Can anyone provide an easy to understand example? I've reviewed the Oracle documentation, but I'm not fully understanding the Index portion or how exactly to specify what I'm after in proper syntax - http://www.dba-oracle.com/t_sql_contains_clause.htm.
Try:
when location like '%To be auctioned%' then 4
You have to account for upper and lower case, and sometimes accented characters.
é anyone?
WHEN instr(UPPER(LOCATION)),'AUCTION') > 0 THEN 4
To account for words with accents you need to use REPLACE to change é to e and then compare

Manipulating a record data

I am looking for a way to take data from one table and manipulate it and bring it to another table using an SQL query.
I have a Column called NumberStuff that has data like this in it:
INC000000315482
I need to cut off the INC portion of the number and convert it into an integer and store it into a Column in another table so that it ends up looking like this:
315482
Any help would be much appreciated!
Another approach is to use the Replace function. Either in TSQL or as a Derived Column Expression in SSIS.
TSQL
SELECT REPLACE(T.MyColumn, 'INC', '') AS ReplacedINC
SSIS
REPLACE([MyColumn], "INC", "")
This removes the character based data. It then becomes an optional exercise in converting to a numeric type before storing it to the target table or letting the implicit conversion happen.
Simplest version of what you need.
select cast(right(column,6) as int) from table
Are you doing this in a SSIS statement, or?...is it always the last 6 or?...
This is a little less dependant on your formatting...removes 0's and can be any length (will trim the first 3 chars and the leading 0's).
select cast(SUBSTRING('INC000000315482',4,LEN('INC000000315482') - 3) as int)

How do I sort a VARCHAR column in PostgreSQL that contains words and numbers?

I need to order a select query using a varchar column, using numerical and text order. The query will be done in a java program, using jdbc over postgresql.
If I use ORDER BY in the select clause I obtain:
1
11
2
abc
However, I need to obtain:
1
2
11
abc
The problem is that the column can also contain text.
This question is similar (but targeted for SQL Server):
How do I sort a VARCHAR column in SQL server that contains words and numbers?
However, the solution proposed did not work with PostgreSQL.
Thanks in advance, regards,
I had the same problem and the following code solves it:
SELECT ...
FROM table
order by
CASE WHEN column < 'A'
THEN lpad(column, size, '0')
ELSE column
END;
The size var is the length of the varchar column, e.g 255 for varying(255).
You can use regular expression to do this kind of thing:
select THECOL from ...
order by
case
when substring(THECOL from '^\d+$') is null then 9999
else cast(THECOL as integer)
end,
THECOL
First you use regular expression to detect whether the content of the column is a number or not. In this case I use '^\d+$' but you can modify it to suit the situation.
If the regexp doesn't match, return a big number so this row will fall to the bottom of the order.
If the regexp matches, convert the string to number and then sort on that.
After this, sort regularly with the column.
I'm not aware of any database having a "natural sort", like some know to exist in PHP. All I've found is various functions:
Natural order sort in Postgres
Comment in the PostgreSQL ORDER BY documentation

What is the best way to select string fields based on character ranges?

I need to add the ability for users of my software to select records by character ranges.
How can I write a query that returns all widgets from a table whose name falls in the range Ba-Bi for example?
Currently I'm using greater than and less than operators, so the above example would become:
select * from widget
where name >= 'ba' and name < 'bj'
Notice how I have "incremented" the last character of the upper bound from i to j so that "bike" would not be left out.
Is there a generic way to find the next character after a given character based on the field's collation or would it be safer to create a second condition?
select * from widget
where name >= 'ba'
and (name < 'bi' or name like 'bi%')
My application needs to support localization. How sensitive is this kind of query to different character sets?
I also need to support both MSSQL and Oracle. What are my options for ensuring that character casing is ignored no matter what language appears in the data?
Let's skip directly to localization. Would you say "aa" >= "ba" ? Probably not, but that is where it sorts in Sweden. Also, you simply can't assume that you can ignore casing in any language. Casing is explicitly language-dependent, with the most common example being Turkish: uppercase i is İ. Lowercase I is ı.
Now, your SQL DB defines the result of <, == etc by a "collation order". This is definitely language specific. So, you should explicitly control this, for every query. A Turkish collation order will put those i's where they belong (in Turkish). You can't rely on the default collation.
As for the "increment part", don't bother. Stick to >= and <=.
For MSSQL see this thread: http://bytes.com/forum/thread483570.html .
For Oracle, it depends on your Oracle version, as Oracle 10 now supports regex(p) like queries: http://www.psoug.org/reference/regexp.html (search for regexp_like ) and see this article: http://www.oracle.com/technology/oramag/webcolumns/2003/techarticles/rischert_regexp_pt1.html
HTH
Frustratingly, the Oracle substring function is SUBSTR(), whilst it SQL-Server it's SUBSTRING().
You could write a simple wrapper around one or both of them so that they share the same function name + prototype.
Then you can just use
MY_SUBSTRING(name, 2) >= 'ba' AND MY_SUBSTRING(name, 2) <= 'bi'
or similar.
You could use this...
select * from widget
where name Like 'b[a-i]%'
This will match any row where the name starts with b, the second character is in the range a to i, and any other characters follow.
I think that I'd go with something simple like appending a high-sorting string to the end of the upper bound. Something like:
select * from widgetwhere name >= 'ba' and name <= 'bi'||'~'
I'm not sure that would survive EBCDIC conversion though
You could also do it like this:
select * from widget
where left(name, 2) between 'ba' and 'bi'
If your criteria length changes (as you seemed to indicate in a comment you left), the query would need to have the length as an input also:
declare #CriteriaLength int
set #CriteriaLength = 4
select * from widget
where left(name, #CriteriaLength) between 'baaa' and 'bike'