SQL Server Parsing Thai Language Full Name to First Last - sql

I have a unique issue. I've worked a long time with SQL Server. We import a file into SQL Server that includes Full Name. All I need to do is parse the full name into First and Last. If the name is English character set, my parse works fine. But, we're parsing Thai names which uses a different character set?
This is my code:
DECLARE #FullName NVARCHAR(MAX) = N'กล้วยไม้ สวามิวัศดุ์'
SELECT
LEN(#FullName) AS StringLength,
#FullName AS FullName,
REVERSE(#FullName) AS ReverseName,
LEFT(#FullName, LEN(#FullName) - CHARINDEX(' ', REVERSE(#FullName))) AS FirstName,
STUFF(RIGHT(#FullName, CHARINDEX(' ', REVERSE(#FullName))),1,1,'') AS LastName;
Results:
20 กล้วยไม้ สวามิวัศดุ์ ์ุดศัวิมาวส ้มไยว้ลก กล้วยไม้ สวามิวัศดุ์ NULL
Like I said, the query works fine when I use english. For example, 'John Smith' returns:
10 John Smith htimS nhoJ John Smith
I have searched this and other sites all day! Thanks in advance.

I've seen this (IMO) complicated logic involving reverse and stuff previously and do not understand the purpose of using reverse. It just seems overly complicated to me. Below does what you want without using reverse.
set nocount on;
declare #names table (FullName nvarchar(40) not null);
insert #names (FullName) values (N'กล้วยไม้ สวามิวัศดุ์'), (N'John Smith'), (N'Bozo Clown'), (N'Eva Perón'), (N'Stefan Löfven');
select * from #names;
select
LEN(FullName) AS StringLength,
FullName AS FullName,
LEFT(FullName, CHARINDEX(N' ', FullName)) AS FirstName,
RIGHT(FullName, len(FullName) - CHARINDEX(N' ', FullName) + 1) as LastName,
STUFF(FullName, 1, CHARINDEX(N' ', FullName), N'') as LName
from #names
;
For consistency (a habit you should develop) I've changed your string literals from ansi strings to unicode strings (prefaced with N'). And a word of warning - names are complicated. Verify your assumption about always having 2 part names.

Related

Concatenating Full Names in Microsoft SQL Server

Suppose I have a table with the following information
Title FirstName MiddleName LastName Suffix
======|============|=============|============|======
Mr. John Fitzgerald Kennedy NULL
NULL John NULL Doe III
I want to create a query to output the full name of the above information. For example, I want the output to look like
Mr. John Fitzgerald Kennedy
John Doe, III
I was thinking of using the concat() function, but I am unsure how to go about this to ensure I don't have extra spaces or hanging commas in the names.
This is a little tricky. SQL Server 2017+ supports concat_ws(). However, you still need a comma for the suffix. Forturnately, concat() ignores NULLs:
select concat(concat_ws(' ', title, firstname, middlename, lastname),
', ' + suffix
)
Earlier versions require a bit more work to avoid multiple spaces when there are NULL values:
select ltrim(concat(' ' + title,
' ' + firstname,
' ' + middlename,
' ' + lastname,
', ' + suffix
)
)
This uses the fact that + returns NULL when an argument is NULL. But, concat() ignores it.
Note: Neither probably does what you want if all the names are NULL but the suffix is present. However, I doubt that is an issue in your data.
Here is a db<>fiddle.

SQL Server 2008 - Remove the parentheses and anything between

I am having a hard time to figure out how to remove the parentheses and anything inside it, plus the space in front. I tried the combination of CharIndex, Substring, and LEFT, but could not get it work correctly.
Here is the example. Let's say I have a very simple table "ContactName" and a column "DisplayName"
Query would be "Select DisplayName FROM ContactName".
In the ContactName table, the data looks like this:
Joe Blow (joe.blow#yahoo.com)
John Deep (jdeep#gmail.com)
(Tim.King#gmail.com) King, Timothy
Richard Harris
Wang, Justin
What I would like to do is removing anything with the parenthesis including the space in front of it if any. For example, "Joe Blow (joe.blow#yahoo.com)" will become "Joe Blow" with NO space, not "Joe Blow ". Also, "(Tim.King#gmail.com) King, Timothy" will become "King, Timothy"
Example of the result would be like this, and NO trailing spaces after the name.
Joe Blow
John Deep
King, Timothy
Richard Harris
Wang, Justin
Maybe I need some kind of RegEx to accomplish this. Please help.
Thanks in advance,
To remove all characters between ( and ) in the string (if they are present), you can use stuff and then a combination of ltrim and rtrim to remove all the trailing and leading spaces.
case when charindex('(',displayname) > 0 and charindex(')',displayname) > 0
then rtrim(ltrim(stuff(displayname,charindex('(',displayname),charindex(')',displayname),'')))
else displayname end
Here is one rather brute force way that works when the parentheses are either at the beginning or end:
select (case when displayname like '(%'
then stuff(displayname, 1, charindex(') ', displayname + ') '), '')
when displayname like '%)'
then left(displayname, charindex(' (', displayname + ' ('))
else displayname
end)
Not an idea solution, but SQL Server doesn't have great support for strings.
Here's another approach:
DECLARE #Table TABLE (DisplayName VARCHAR(100))
INSERT INTO #Table
VALUES ('Joe Blow (joe.blow#yahoo.com)'),
('John Deep (jdeep#gmail.com)'),
('(Tim.King#gmail.com) King, Timothy'),
('Richard Harris'),
('Wang, Justin')
SELECT RTRIM(
LTRIM(
REPLACE(DisplayName,
SUBSTRING( DisplayName,
CHARINDEX('(',DisplayName,1),
((CHARINDEX(')',DisplayName, 1)) - (CHARINDEX('(',DisplayName,1))+1)
),
'')
)
)
FROM #Table

extracting last name from a name string in ORACLE DB

I am writing a small query to extract all last names from a bunch of Author name database. Names on file will contain first and middle name, or just first name.
Ex: John Smith
John T. Smith
So I cannot search purely by just after the first space... But I know for sure that the lastname should be from the END to the first space from the right side of the string. I don't really care about first name.
This is what I currently have...
select [name], LEFT([name], CHARINDEX(' ', [name] + ' ')-1) as firstName,
SUBSTRING([name], charindex(' ', [name]+' ') + 1, LEN([name])) as lastName
from Author
;
I am quite new to sql, any help is highly appreciated!
Thanks in advance!
EDIT: for those who ever come across this need for help, this line helps:
select substr(t.string,instr(t.string,' ',-1)+1) last_word
For Oracle DB try this :
WITH t AS
(SELECT name AS l FROM <your query>
)
SELECT SUBSTR(l,instr(l,' ',-1)+1,LENGTH(l)) FROM t;
SUBSTRING_INDEX() should work in this case.
select name, SUBSTRING_INDEX(name,' ',-1) as lastName from Author;

Split and merge string

I'm trying to generate an email from full name. Following is what I have and I'm stuck here
select distinct tbin.Name
,(SELECT SUBSTRING(tbin.Name, 1, CHARINDEX(' ', tbin.Name) - 1) AS [FirstName])
,(select SUBSTRING(tbin.Name, CHARINDEX(' ', tbin.Name) + 1, 8000) AS LastName)
from tblInitialApplicants tbin
Name is like 'Natalie Marine Baily'. Name can be of any length and also can have any number of space between each part of the name.
Expected result: Natalie.B#gmail.com
'Natalie' - First Name
'B' - First letter of the last name
You can get the position of a char with CHARINDEX, look for the first space and reverse de name and look for the last. With that you can easly substring first and last name.
DECLARE #Fullname VARCHAR(100) = 'Natalie Marine Baily';
select
*,
firstname+'.'+lastnameINITIAL+'#gamil.com'
from (
select
#Fullname Fullname,
SUBSTRING(#Fullname,1,CHARINDEX(' ',#Fullname,1)) firstname,
SUBSTRING(SUBSTRING(#Fullname,LEN(#Fullname)-CHARINDEX(' ',REVERSE(#Fullname),1)+2,CHARINDEX(' ',REVERSE(#Fullname),1)),1,1) lastnameINITIAL
) T
DECLARE #name VARCHAR(200) = 'Natalie Marine Baily'
SELECT LEFT(#name,CHARINDEX(' ',#name,1)-1) + '.'+
LEFT(REVERSE(LEFT(REVERSE(#name),CHARINDEX(' ',REVERSE(#name),1)-1)),1) + '#gmail.com'
Result:
Just see, whether you can work from here.
Your biggest problem is that both first names and last names can have spaces between them. So how will you know where the last name begins? For example Jean-Claude Van Damme.
Also what should the email look like in this case? jean-claude.v#gmail.com?
I would suggests you change your database to store the first and last names as separate fields, or better yet have an email field. Then this will be much easier. If you cannot do that you will have to generate a few possible emails and validate if the emails exist.
How to check if an email address exists without sending an email?
This would be how to generate an email if you take it that the first word is the firstname and the last word is the lastname.
DECLARE #Name varchar(100) = 'Natalie Marine Baily'
select SUBSTRING(#Name, 0, CHARINDEX(' ', #Name) - 1)
+ '.' + SUBSTRING(#Name,LEN( #Name) - CHARINDEX(' ',REVERSE(#Name))+2 , 1) + '#gmail.com'

How to parse a row in SQL into columns (separator-spaces)

I need to parse row (with spaces) into two different columns in SQL. The rows look like that:
FullName
John Mayer
Rajon Jennings
Donna Fraye
Michael Moore
So the expected result is :
Name
John
Rajon
Donna
Michael
Surname
Mayer
Jennings
Fraye
Moore
How can i do that in SQL?
If you have a requirement like First Name should be string before first space and rest everything what follows should go as Last name , you can update two columns as:
Update T
Set T.FirstName = Left(ltrim(rtrim(FullName)), CHARINDEX(' ',ltrim(rtrim(FullName))))
,T.LastName = Right(ltrim(rtrim(FullName)),len(FullName)- CHARINDEX(' ',ltrim(rtrim(FullName))))
From Test T
Check Demo here..
You can use a split function.This function must be created.
Here are some examples :
http://ole.michelsen.dk/blog/split-string-to-table-using-transact-sql/
Split function by comma in SQL Server 2008
If there is only ever 1 space / 2 name and you don't have to cater for names like Vincent van Gough, then a combination of substring and charindex should do.
select substring(fullname, 1, charindex(' ', fullname)) as name,
substring(fullname, charindex(' ', fullname)+1, len(fullname)-charindex(' ', fullname)) as surname
from tbl
This does not cover people with the same first and last name (ie. john john) but will work for rest. Not recommended but is a different solution.
select left(fullname, charindex(' ',fullname)) Name,
replace(fullname,left(fullname, charindex(' ',fullname)),'') Surname
from names
Fiddle