Oracle SQL - See if Value Contains Substrings from Three Other Values - sql

I have three columns for a person's name (first middle last) and a column for a user ID.
The purpose of this code is to find persons with a UserID that does not match their name.
The UserID is created by taking the FIRST letter of the first name, the FIRST letter of the middle name and the FULL last name. Mary Jane Smith would have the UserID of MJSmith34. Random numbers are added to the end when there is more than one MJSmith, but this does not matter for what I need.
The code below compares the person's last name in two areas. If they do not match, it means that the person's name has been changed. What I need now is to check the UserID against the most current First Middle Last name to see if the UserID need to be changed (updated). The Pseudocode is what I need, but I am not sure if it can even be done. Please help!!
Select DISTINCT
NL.spriden_id as "STU_ID",
NL.SPRIDEN_LAST_NAME as "Last_Name" ,
NL.SPRIDEN_FIRST_NAME as "First_Name"
FROM SARADAP SA
JOIN SPRIDEN NM -- NM is Name
ON SA.SARADAP_PIDM = NM.SPRIDEN_PIDM
JOIN SPRIDEN NL -- NL is null
ON SA.SARADAP_PIDM = NL.SPRIDEN_PIDM
JOIN IDTABLE ID
ON ST.SOMETABLE_PIDM = ID.IDTABLE_PIDM =
WHERE
NM.SPRIDEN_CHANGE_IND LIKE '%N%'
AND
NL.SPRIDEN_CHANGE_IND IS NULL
AND
NL.SPRIDEN_ACTIVITY_DATE between sysdate - 10 and sysdate
AND
NL.spriden_id LIKE 'A00%'
AND
lower(NL.SPRIDEN_LAST_NAME) <> lower(NM.SPRIDEN_LAST_NAME)
AND
NL.SPRIDEN_ACTIVITY_DATE <> NM.SPRIDEN_ACTIVITY_DATE
Pseudocode -
I know I need something with the POSITION of the characters.
I need help making this pseudocode into real code, please! :)
AND ID.USERID LIKE '%(NL.SPRIDEN_LAST_NAME)%'
AND SUBSTRING (1st CHAR OF ID.USERID) LIKE
SUBSTRING FIRST CHARACTER OF (NL.SPRIDEN_FIRST_NAME)
AND SUBSTRING (2nd char of ID.USERID) LIKE
SUBSTRING FIRST CHAR OF (NL.SPRIDEN_MIDDLE_NAME)

AND ID.USERID LIKE SUBSTR(NL.SPRIDEN_FIRST_NAME, 1, 1)
|| SUBSTR(NL.SPRIDEN_MIDDLE_NAME, 1, 1)
|| NL.SPRIDEN_LAST_NAME || '%'
|| is a concatenation operator
This condition means: check if USERID starts with the first symbol SPRIDEN_FIRST_NAME + the first symbol of SPRIDEN_MIDDLE_NAME + SPRIDEN_LAST_NAME

A slight variation on Multisync's good answer:
AND REGEXP_LIKE(ID.USERID, SUBSTR(NL.SPRIDEN_FIRST_NAME, 1, 1)
|| SUBSTR(NL.SPRIDEN_MIDDLE_NAME, 1, 1)
|| NL.SPRIDEN_LAST_NAME || '[0-9]*$', 'i')
-- ^
-- case insensitive compare
That way you won't have false positive for cases such as James Tiberius Kirk => jtkirkwood and you get case insensitive compare "for free".
The drawback here is I assume you don't have regex special characters as part of the name of your users...
Think about normalizing case too!

Related

Find the names of employees whose name has more than two ā€˜aā€™ in it and ends with ā€˜sā€™. ORACLE SQL

I'm attempting to select from a table the names of employees whose name has two 'a' in it and end with s. Heres what I have so far
select NAME from CLASS where NAME LIKE '%s'
I know how to find names where they end with s but not sure how to search for names having atleast two 'a'.
Am I missing something, or could you just not just write
select NAME from CLASS where LOWER(NAME) LIKE '%a%a%a%s'
?
This selects every name that has at least three (i.e. more than two) as, and ends with an s.
One option might be
where regexp_count(name, 'a', 1, 'i') = 2
and substr(lower(name), -1) = 's'
number of 'a' letters - starting at position 1, performing case insensitive search ('i') = 2
the last character is 's'
Found a solution:
select NAME from CLASS where NAME LIKE '%s' and REGEXP_COUNT(NAME, 'a') > 2;
Try this:
select NAME from test where regexp_like(NAME,'[a]{2}[a-z]*[s]$');

Exact last character match in string

My requirement is to match the below characters with the values present in a table column.These characters should be the value in a string.
Characters :
JR
SR
II
III
Table Column values could be :
'MANFORTI JR','KRUMPAK III','PURDY II','MARRONE SR'
if the characters gets matched with the column values then just fetch the
character values and consider it as suffix for the name.
Problem :
The problem is occurring when trying to match II. The value is being fetched
where the column value has III in the string.(Please refer attached screenshot)
Could you please suggest how to do the exact match ?
I come up with the below queries to match the string..
SELECT LAST_NAME A,
CASE WHEN REGEXP_INSTR(LAST_NAME, 'JR$') > 0
THEN SUBSTR(LAST_NAME,REGEXP_INSTR(LAST_NAME, 'JR$'), LENGTH(LAST_NAME))
WHEN REGEXP_INSTR(LAST_NAME, 'SR$') > 0
THEN SUBSTR(LAST_NAME,REGEXP_INSTR(LAST_NAME, 'SR$'), LENGTH(LAST_NAME))
WHEN REGEXP_INSTR(LAST_NAME, 'II$') > 0
THEN SUBSTR(LAST_NAME,REGEXP_INSTR(LAST_NAME, '[II]$'), LENGTH(LAST_NAME))
END SUFFIX
FROM TBL_LAST_NAME
WHERE LAST_NAME IN ('MANFORTI JR','KRUMPAK III','PURDY II','MARRONE SR')
Output :
Prepend a space before the suffix (and you can also use LIKE rather than, more expensive, regular expressions)
SELECT LAST_NAME AS A,
CASE
WHEN LAST_NAME LIKE '% JR'
OR LAST_NAME LIKE '% SR'
OR LAST_NAME LIKE '% II'
THEN SUBSTR(LAST_NAME,-2)
WHEN LAST_NAME LIKE '% III'
THEN SUBSTR(LAST_NAME,-3)
END AS SUFFIX
FROM TBL_LAST_NAME
WHERE LAST_NAME IN ('MANFORTI JR','KRUMPAK III','PURDY II','MARRONE SR')
If you want to use regular expressions then:
SELECT LAST_NAME AS A,
REGEXP_SUBSTR(
last_name,
'\W(SR|JR|II|III)$', -- Match a non-word character then suffix
-- at end-of-string
1, -- Start from the 1st character
1, -- Find the 1st match
'i', -- Case insensitive
1 -- Return the 1st capture group
) AS suffix
FROM TBL_LAST_NAME
WHERE LAST_NAME IN ('MANFORTI JR','KRUMPAK III','PURDY II','MARRONE SR')

Changing LastName,FirstName to LastName,FirstInitial

I'm sure this is super easy, but how would I go about converting LastName,FirstName to LastName,FirstInitial?
For example changing Smith,John to Smith,J or Johnson,John to Johnson,J etc.
Thank You!
In case of LastName and FirstName columns:
select LastName,substr(FirstName,1,1)
from mytable
;
In case of a fullname saved in a single column:
select substr(fullname,1,instr(fullname || ',',',')-1) || substr(fullname,instr(fullname || ',',','),2)
from mytable
;
or
select regexp_replace (fullname,'([^,]*,?)(.).*','\1\2')
from mytable
;
Here is one way, using just "standard" instr and substr. Assuming your input is a single string in the format 'Smith,John':
select substr(fullname, 1, instr(fullname, ',')+1) from yourtable;
yourtable is the name of the table, and fullname is the name of the column.
instr(fullname, ',') finds the position of the comma within the input string (it would be 6 in 'Smith,John'); thensubstrtakes the substring that begins at the first position (the1in the function call) and ends at the position calculated byinstr`, PLUS 1 (to get the first initial as well).

Select statement with column contains '%'

I want to select names from a table where the 'name' column contains '%' anywhere in the value. For example, I want to retrieve the name 'Approval for 20 % discount for parts'.
SELECT NAME FROM TABLE WHERE NAME ... ?
You can use like with escape. The default is a backslash in some databases (but not in Oracle), so:
select name
from table
where name like '%\%%' ESCAPE '\'
This is standard, and works in most databases. The Oracle documentation is here.
Of course, you could also use instr():
where instr(name, '%') > 0
One way to do it is using replace with an empty string and checking to see if the difference in length of the original string and modified string is > 0.
select name
from table
where length(name) - length(replace(name,'%','')) > 0
Make life easy on yourselves and just use REGEXP_LIKE( )!
SQL> with tbl(name) as (
select 'ABC' from dual
union
select 'E%FS' from dual
)
select name
from tbl
where regexp_like(name, '%');
NAME
----
E%FS
SQL>
I read the documentation mentioned by Gordon. The relevent sentence is:
An underscore (_) in the pattern matches exactly one character (as opposed to one byte in a multibyte character set) in the value
Here was my test:
select c
from (
select 'a%be' c
from dual) d
where c like '_%'
The value a%be was returned.
While the suggestions of using instr() or length in the other two answers will lead to the correct answer, they will do so slowly. Filtering on function results simply take longer than filtering on fields.

Select only when the field has more than one word

SELECT name FROM clients;
Table clients
id | name |
1 John
2 John Bravo
3 John Alves
4 Jo
In postgres, how can I select only names with more than one word? For example. This should be the output:
John Bravo
John ALves
I think just test if the name contains a space: where name like '% %'
But this will give you some problem if you name can contain space char befor or after the name, like: ' JOHN' or 'Luck '
If word means to you a space delimited token, then the following would do the trick:
SELECT name FROM clients WHERE name LIKE '% %';
But this will also give you those that have empty names made out of spaces only. Also performance-wise, this will be a costly query.
First you may have to find the number of words in the column, then only select where the number of words is greater than 1.
For example:
SELECT LENGTH(name) - LENGTH(REPLACE(name , ' ', ''))+1 FROM clients;
This will return the number of words in each row, which we have in the field name.
Then you can proceed putting this in a nested select SQL statement something like :
SELECT LENGTH(name) - LENGTH(REPLACE(name, ' ', ''))+1 as mycheck, name FROM clients where (SELECT LENGTH(name) - LENGTH(REPLACE(name, ' ', ''))+1)>1
This will return only where words are greater than 1 (>1). Else you can user >2 to return columns with more than 2 words.
LIKE is an option, or you can use split_part:
SELECT name FROM clients WHERE split_part(trim(name), ' ', 2) <> ''