简体   繁体   中英

How to query “LastName, FirstName” from “FirstName LastName” when there may be middle initials?

Field contains first and last names.

PERSON:
Bob Franklin
Gene Smith
Roy G. Biv

I am trying to create a query that puts the last name first, then a comma, then the first name. That part is not a problem. The problem I am having is with Roy G. Biv. Instead of returning his last name, I am getting G. Biv. I wrote a separate query that returns the last name correctly, but I don't know how to implement the two together.

SELECT DISTINCT PERSON, SUBSTR(PERSON,INSTR(PERSON,' ')+1)|| ', '|| substr(person,1,INSTR(person,' ') -1) AS PERSONS
FROM LEDGER

This returns:

Franklin, Bob
Smith, Gene
G. Biv, Roy

This query gives me the results I want from the name with the middle initial:

select distinct person, SUBSTR(PERSON,INSTR(PERSON,'.')+1)
from ledger
where person like '%BIV'

Returns:

Biv

What is the best way to combine these? I am really new with SQL, go easy on me! Thanks!

You can search the position of the space counting backwards. Check the documentation for INSTR here :

SELECT DISTINCT PERSON, SUBSTR(PERSON,INSTR(PERSON,' ',-1,1)+1)|| ', '|| substr(person,1,INSTR(person,' ') -1) AS PERSONS
FROM LEDGER

Quote from the documentation:

Example 7-128 Using Character Position to Search Backward to Find the Position of a Substring

In this next example, the function counts backward from the last character to the third character from the end, which is the first "o" in "Floor". The function then searches backward for the second occurrence of "or", and finds that this second occurrence begins with the second character in the search string.

 SHOW INSTR('Corporate Floor','or', -3, 2) 2 

usually names separated by space, so it is easier to use substring_index:

SELECT 
  substring_index(PERSON, ' ', 1) AS first_name,
  substring_index(PERSON, ' ',-1) AS last_name
FRON ledger

And then if you want to re-format as 'last_name, first_name':

SELECT concat(
  substring_index(PERSON, ' ',-1),
  ', ',
  substring_index(PERSON, ' ', 1)
) AS full_name
FRON ledger

I have been designing user table for years using first_name, last_name, and sometimes middle_name or other_names.

And I find nearly all times use full name. So if you are most times using full names, one field is actually better.

SELECT CONCAT(SUBSTRING_INDEX(PERSON, ' ',-1),', ' ,SUBSTRING_INDEX(PERSON, ' ',1)) FROM LEDGER

Oracle solution

select  regexp_replace (person,'(\S+)(\s+\S+)?\s+(\S+)','\3, \1') as persons
from    ledger

+----------------+
|    PERSONS     |
+----------------+
|  Franklin, Bob |
|  Smith, Gene   |
|  Biv, Roy      |
+----------------+

\s - A whitespace character.
\S - A non-whitespace character.
+  - Matches one or more occurrences
?  - Matches zero or one occurrence

REGEXP_REPLACE
Oracle Regular Expression Support

你可以用这个

substr(PERSON,INSTR(PERSON,' ', -1) )||', '|| substr(PERSON,1,INSTR(PERSON,' ', -1) )

You can use directly below mentioned select statement.

select substr(PERSON,instr(PERSON,' ',-1))||', '||substr(PERSON,instr(PERSON,' ',1),instr(PERSON,' ',-1)-instr(PERSON,' ',1))||' '||substr(PERSON,0,instr(PERSON,' ',1)) from ledger;

Or else club it all in with clause and call it from another select clause which will look simple and easy like below:

with temp_ledger as (
select substr(PERSON,instr(PERSON,' ',-1)) as l_name ,substr(PERSON,instr(PERSON,' ',1),instr(PERSON,' ',-1)-instr(PERSON,' ',1)) as m_name, substr(PERSON,0,instr(PERSON,' ',1)) as f_name from ledger )

select l_name||', '||m_name||' '||f_name from temp_ledger;

NOTE: YOU CAN ALSO HANDLE NAME WITH MORE THAN 3 WORDS LIKE "Jean Claude van Damme"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM