Comparing values in oracle when one value is partially masked - sql

Here is what I am trying to do in a Oracle SQL query:
I have an account number that is X characters long (Example: 6001055555). I have a table that has part of the same account number but most of the number is masked (Examples: 600##########, 6001######, 600244####).
I am trying to match the number passed in 6001055555 to one of the following values 600##########, 6001######, 600244####.
In this example, account number 6001055555 should return 6001###### (from the above list). I can get to the point where the lengths are the same but am not sure how to address the match - I am looking at using REGEX expressions but am not sure if that' the correct path.

You can use the regular LIKE comparison in this case:
SQL> WITH DATA AS (
2 SELECT '600##########' acct FROM dual UNION ALL
3 SELECT '6001######' acct FROM dual UNION ALL
4 SELECT '600244####' acct FROM dual
5 )
6 SELECT *
7 FROM DATA
8 WHERE '6001055555' LIKE REPLACE (acct, '#', '_');
ACCT
-------------
6001######
We're used to seeing COLUMN LIKE :var but switching terms is also valid (:var LIKE column).

If my understanding is rite, this is what u may be expecting...
select regexp_substr('6001055555',replace('600##########','#'),1) from dual;
If you got any value from this query you may conclude that the account number is matched with the masking values

Related

max consecutive digits in a string

I am trying to count the number of MAX consecutive digits that appear in a string column, let me give an example to illustrate better what I am trying to do. If I have a table called email
email
lucas1234#gmail.com
fer12#gmail.com
lupal#gmail.com
carlos1perez222#gmail.com
carlos11perez222#gmail.com
lucila1#gmail.com
my expected output would be
email count_cons_digits
lucas1234#gmail.com 4
fer12#gmail.com 2
lupal#gmail.com 0
carlos1perez222#gmail.com 3
carlos11perez222#gmail.com 3
lucila1#gmail.com 1
Check that this question is very similar to :
Number of consecutive digits in a column string
but the only difference is that the function from the results is not contemplating cases with only one digit in the email (like lucila1#gmail.com). In this case, the expected result should be 1 but the proposed function is giving 0. And also whenever the email contains "two sections" of consecutive digits (carlos11perez222#gmail.com). In this case, the expected output is to be 3 but is given 5.
Consider below approach
select *,
ifnull((select length(digits) len
from unnest(regexp_extract_all(email, r'\d+')) digits
order by len desc
limit 1
), 0) as count_cons_digits
from your_table
if applied to sample data in your question - output is
You may also try this approach using regex:
WITH email AS
(SELECT 'lucas1234#gmail.com' mail,
UNION ALL SELECT 'fer12#gmail.com',
UNION ALL SELECT 'lupal#gmail.com',
UNION ALL SELECT 'carlos1perez222#gmail.com',
UNION ALL SELECT 'carlos11perez222#gmail.com',
UNION ALL SELECT 'lucila1#gmail.com')
SELECT email,
(LENGTH(REGEXP_REPLACE(REGEXP_REPLACE(email.mail, r'[A-Za-z]+\d+[A-Za-z]+', ''),r'[A-Za-z.#]+',''))) AS count_cons_digits,
FROM email;
Output:

how can function SUBSTR can help me remove vlues from my column

25779101724|GTG1105-Kibimba .These are the telefone numbers, there is more like this.After the numbers the following characters are a location of the telefone number. so i want to remove everything after these numbers(the bar,the location, and the space) so that i can query in the db the numbers which are active among these. and then i dont want to lose these location after numbers because i will need them to report the active numbers AND their location. how can i remove these location and query the active numbers and then replace the location.
I am hoping a response.
From my point of view, your by far the best option is to normalize that table and store each piece of information into its own column. Because, as long as you can easily split that string into several parts, joining it to another table will suffer as number of rows gets higher.
Anyway, here you are.
Sample data:
SQL> with test (msisdn) as
2 (select '25779101724|GTG1105-Kibimba' from dual union all
3 select '25776030896|BRR1351-Kaberenge2' from dual
4 )
Query begins here:
5 select
6 substr(msisdn, 1, instr(msisdn, '|') - 1) phone_number,
7 substr(msisdn, instr(msisdn, '|') + 1) the_rest
8 from test;
PHONE_NUMBER THE_REST
------------------------------ ------------------------------
25779101724 GTG1105-Kibimba
25776030896 BRR1351-Kaberenge2
SQL>

Dual command in Big Query

"I am trying to achieve dual command in big query"
"I tried using the temp tables but not able to achieve it"
Oracle query: SELECT LEVEL - 1 F FROM
DUAL CONNECT BY LEVEL <= 2
"I expect the output in below format "
F
1
2
I have salary table with salaries : 50$ and 200$
I want to have duplicate of each row : 50$ ,-50$,200$ and -200$ is the output which i am expecting like 4 rows in total
You can use
SELECT
1
from (
select SESSION_USER())
to return a resultset with just one row.
Since BigQuery doesn't support CONNECT BY clause and since you want to get a positive and negative values from your data, you could try using a simple query like this one:
SELECT my_value FROM `project.dataset.table`
UNION ALL
SELECT -my_value FROM `project.dataset.table`
Notice the - in the second query as it'll give you negative values.
Hope it helps.

Extracting number of specific length from a string in Postgres

I am trying to extract a set of numbers from comments like
"on april-17 transactions numbers are 12345 / 56789"
"on april-18 transactions numbers are 56789"
"on may-19 no transactions"
Which are stored in a column called "com" in table comments
My requirement is to get the numbers of specific length. In this case length of 5, so 12345 and 56789 from the above string separately, It is possible to to have 0 five digit number or more more than 2 five digit number.
I tried using regexp_replace with the following result, I am trying the find a efficient regex or other method to achieve it
select regexp_replace(com, '[^0-9]',' ', 'g') from comments;
regexp_replace
----------------------------------------------------
17 12345 56789
I expect the result to get only
column1 | column2
12345 56789
There is no easy way to create query which gets an arbitrary number of columns: It cannot create one column for one number and at the next try the query would give two.
For fixed two columns:
demo:db<>fiddle
SELECT
matches[1] AS col1,
matches[2] AS col2
FROM (
SELECT
array_agg(regexp_matches[1]) AS matches
FROM
regexp_matches(
'on april-17 transactions numbers are 12345 / 56789',
'\d{5}',
'g'
)
) s
regexp_matches() gives out all finds in one row per find
array_agg() puts all elements into one array
The array elements can be give out as separate columns.

DB2: fill a dummy field with values in for loop while a select

I want to fill a dummy field with values in a for loop during a select:
Somethinhg like (table account e.g. has a field "login")
select login,(for i= 1 to 3 {list=list.login.i.","}) as list from account
The result should be
login | list
aaa | aaa1,aaa2,aaa3
bbb | bbb1,bbb2,bbb3
ccc | ccc1,ccc2,ccc3
Can someone please help me if that is possible !!!!
Many Thanks !
If this is an one-off task and the size of your loop is fixed, you can make up a table of integers and do a cartesian product with your table containing the column login:
SELECT ACC.LOGIN || NUMBRS.NUM FROM
ACCOUNT ACC, TABLE (
SELECT '1' AS NUM FROM SYSIBM.SYSDUMMY1 UNION
SELECT '2' AS NUM FROM SYSIBM.SYSDUMMY1 UNION
SELECT '3' AS NUM FROM SYSIBM.SYSDUMMY1
) NUMBRS
which will give you strings like 'aaa1', 'aaa2', 'aaa3' one string per row. Then, you can aggregate these strings with LISTAGG.
If the size is not fixed, you can always make up a temporary table and fill it up with appropriate data and use it instead of the NUMBRS table above.