August 19, 2004 at 10:45 am
I am trying to take a name field and divide it into three fields called Firstname, MI, LastName. The data is in a format like Smith, John L most of the time, but sometimes the full middle name is listed like Smith, John Lee or there is no MI to break out. I only need it to break out into John L Smith. If worst comes to worst I would take a clean First and Last name. I have been tweaking the following query and I am close to getting what I need. If anyone can help with the final couple tweaks I would greatly appreciate it. thanks
SELECT SUBSTRING(NAME,1,CHARINDEX(',',NAME)-1) as LastName,
SUBSTRING(NAME,CHARINDEX(',',NAME)+1,LEN(NAME)) as FirstName,
RIGHT(NAME, 1) AS MI
from maystaff
August 19, 2004 at 2:49 pm
I hate doing string manipulation like this, but here you go. REVERSE makes it possible. I would consider this to be a good candidate for a function if you actually need to do this in more than one spot. Egads its ugly looking.
SELECT SUBSTRING(NAME,1, CHARINDEX(',', NAME)-1) as LastName,
LTRIM(SUBSTRING(NAME, CHARINDEX(',', NAME) + 1, LEN(NAME) - CHARINDEX(' ', REVERSE(NAME)) - CHARINDEX(',', NAME))) as FirstName,
RIGHT( SUBSTRING(REVERSE(NAME), 1, CHARINDEX(' ', REVERSE(NAME))-1), 1) AS MI
FROM maystaff
August 20, 2004 at 8:33 am
There are lots of person name forms. In addition to the standard first name/last name, first name/middle initial/last name, and first name/middle name/last name, there are also:
(1) First initial/middle name/last name
(2) Only one name. (I'm talking about ordinary people, not celebrity stage names.)
(3) Multiple middle names.
(4) Jr., Sr., III, and so on
Yes, these are legal names - they're on passports, driver's licenses, and so on.
In some circumstances, various titles, affiliations, status are also part of the name, such USMC, USMC, Ret (at the end) and "Lt" etc at the front.
And, the "last" name is not necessarily the "family name" or the name that you'd prepend with "Mr" - in some cultures, that's the first name. And, some of these folks have dealt with systems that don't understand this before so they'll use both orders even when dealing with the same organization. (They can't be expected to remember if your organization is one that they have to adjust to by reversing their name.)
August 25, 2004 at 11:48 am
Thanks for the help. I know this kind of stuff isn't much fun. The query you posted almost does it with one problem. It bombs out at the first record that has no Middle Initial. Can I build in a contingency so it won't bomb out? thanks
August 25, 2004 at 12:23 pm
Here's a crude function I use alot. (Posted as a script contribution this AM):
E.G. select dbo.string_field( namecolumn, ' ', 1 ) AS first_name, dbo.string_field( namecolumn, ' ', 2 ) AS middle_name,...
Use case statements counting internal spaces to determine how many words are in the string to find out if there is a middle name...
(I have another funcion I can't find now that encapsulates the counting of characters and one that counts "fields" based on delimiters.)
DROP FUNCTION string_field
GO
CREATE FUNCTION string_field
( @string VARCHAR(4000) = NULL
,@delimiter VARCHAR(20)
,@position INT
) RETURNS VARCHAR(255)
AS
BEGIN
---NOTE: modified because prior version didn't handle space as delimiter
DECLARE @result VARCHAR(255)
,@work VARCHAR(4000)
,@pattern VARCHAR(255)
,@i INT
,@j INT
,@ld INT
SELECT @result = ""
,@ld = LEN( REPLACE( @delimiter, ' ', 'X' ) ) --Incase delimiter is a space LEN will evaluate to zero
--and we don't want that.
IF @position > 0 BEGIN
SELECT @pattern = "%" + @delimiter + "%"
,@work = @string
,@j = 0 --init
WHILE ( @j-2 < @position ) BEGIN
SELECT @i = PATINDEX( @pattern, @work )
,@j = @j-2 + 1
IF @i > 0 BEGIN
SELECT @result = SUBSTRING( @work, 1, @i - 1 )
,@work = SUBSTRING( @work, @i + @Ld, 4000 )
END ELSE BEGIN
IF @j-2 = @position
SELECT @result = @work
ELSE
SELECT @result = ""
,@j = @position
END
END
END
RETURN (@result)
END
GO
Viewing 5 posts - 1 through 4 (of 4 total)
You must be logged in to reply to this topic. Login to reply