How to search name, (OPTIONAL) second name, surname on SQL? - sql

I am not usually an SQL person but need to find matching name/surnames from a list of people on MSSql. I am trying to find similar names from TABLENAME to match the list of people that I have. The line looks like this:
Select *
from TABLENAME(nolock)
Where SomeRule='04' and RTRIM(Name) +' ' + RTRIM(SecondName) +' '+RTRIM(Surname) in (THE LIST OF PEOPLE HERE)
But this method only gives me the match of people with second names. If someone does not have a second name but their name+surname match, it does not show up. I want to see people who have 100% match of name-second name-surname OR name-surname (if they don't have second name).
Thank you guys in advance

Provided list of people is a table
Select distinct t.*
from TABLENAME t
join [THE LIST OF PEOPLE HERE] lp on SomeRule='04'
and RTRIM(t.Name) = lp.Name
and RTRIM(t.Surname) = lp.Surname
and (t.SecondName is null and pl.SecondName is null or RTRIM(t.SecondName) = lp.SecondName)

Let's look at some rows:
Name
SecondName
Surname
Remark
Your concatenation
'John'
'Thomas'
'Smith'
Person with middle name
'John Thomas Smith'
'John'
''
'Smith'
Person that has no middle name
'John  Smith'
'John'
null
'Smith'
Person with an unknown middle name
null
The person without a middle name cannot be found because of two blanks separating first and last name in your created string. The person of whom we don't know the middle name cannot be found because the concatenated string is null.
You can use CASE WHEN to check this and react accordingly:
select *
from tablename
where somerule = '04'
and
rtrim(name) + ' ' +
case when rtrim(secondname) is null then ''
when rtrim(secondname) = '' then ''
else rtrim(secondname) + ' '
end +
rtrim(surname) in (the list of people here)

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

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

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!

OR shows result, AND doesn't show

I have the following problem, a table as simple as
PERSON:
FNAME LNAME AGE
-----------------
John Carl 22
Rupert Luis 24
If I execute the following T-SQL query:
Select *
from PERSON
WHERE FNAME = 'John' AND LNAME = 'Carl'
It doesn't show any results... and if I place an OR instead of AND it does, to me it makes no sense, but it probably is correct, I just want to understand why so?
The way that you have shown the data, there is a space at the beginning of the last name. I don't know if that is true in the original data, but it is true in the query.
Then strings 'CARL' and ' CARL' are not the same. You can do the comparisons as:
where ltrim(rtrim(firstname)) = 'John' and ltrim(rtrim(lastname)) = 'Carl'
Or you could fix the data:
update person
set lastname = ltrim(rtrim(lastname));
Or, there might be another similar problem, typically caused by:
Hidden characters in the string that don't print (often at the beginning or end).
Characters that look similar but are different, such as zero and capital-O.
You are not doing something wrong with AND OR
As the data appears the AND should return the data
Most likely what you have is data that appears to be the same but is not
Do this to figure out which is missing
Select *
from PERSON
WHERE FNAME = 'John'
Select *
from PERSON
WHERE LNAME = 'Carl'
On the one that returns nothing try
Select *
from PERSON
WHERE LNAME like '%Carl%'

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

MS SQL: Retrieving "Varchar" data from 3 columns and combine them together

I have three columns in my sql table, "FirstName", "MiddleName","LastName". When retrieving, I need to display these 3 together, for an example
FirstName = "John"
MiddleName = "Ned"
LastName = "Carter".
On retrieving, these should be displayed as "John Ned Carter".
I tried the following
select FirstName+MiddleName+LastName from PhoneData
There is a problem!!! There are number of Names which the middle name is NULL. There are number of names which the last name is NULL, and so on. This is not retrieving those!!! It simply retrieve names where all the fields are not null!!!! If at least one column is null for a particular name, then it shows the whole name as NULL!!! For an example,
FirstName = "John"
MiddleName = NULL
LastName = NULL
on retrieval, the out put is ' NULL ' , not "John"
Please help!
Try the ISNULL() function around each field. Then you can set a value for when the selected value is null.
Like this;
select ISNULL(FirstName, '') + ISNULL(MiddleName, '') + ISNULL(LastName, '') from PhoneData