问题
For E.g I have a FullName Column in table
FullName
------------------
Smith Johns Sr
James Macoy
Krushit J Patel II
Sheldon Devid
Jeff vandorf Jr
Steve Smith I
And I want to Result Like
|FirstName | Middle Name | lastName | Suffix |
|--------------------------------------------|
|Smith | NULL | Johns | Null |
|James | NULL | Macoy | Null |
|Krushit | J | Patel | II |
|Sheldon | NULL | Devid | Null |
|Jeff | Null | vandorf |Jr |
|Steve |Smith | Ronder |I |
回答1:
As others have commented, the question is too vague (and the problem described too complex) to be able to give a particularly helpful answer, but I will try anyway.
We can propose a solution if we make some assumptions about the name values you're wanting to split:
- Each name contains between 2 and 4 "words", each separated by a single space
- 2 word names are formed:
[First Name] [Last Name]
- 3 word names are formed:
[First Name] [Last Name] [Suffix]
- 4 word names are formed:
[First Name] [Middle Name] [Last Name] [Suffix]
In this case, we could solve as follows (if our names exist in a table called names
with a single column called Name
:
SELECT
SUBSTRING(Name, 1, CHARINDEX(' ', Name) - 1) AS FirstName
,CASE LEN(Name) - LEN(REPLACE(Name, ' ', '')) + 1
WHEN 2 THEN NULL
WHEN 3 THEN NULL
WHEN 4 THEN SUBSTRING(RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name)), 1, CHARINDEX(' ', RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name))) - 1)
END AS [Middle Name]
,CASE LEN(Name) - LEN(REPLACE(Name, ' ', '')) + 1
WHEN 2 THEN RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name))
WHEN 3 THEN SUBSTRING(RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name)), 1, CHARINDEX(' ', RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name))) - 1)
WHEN 4 THEN SUBSTRING(RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name, CHARINDEX(' ', Name) + 1)), 1, CHARINDEX(' ', RIGHT(Name, LEN(Name) - CHARINDEX(' ', Name, CHARINDEX(' ', Name) + 1))) - 1)
END AS lastName
,CASE LEN(Name) - LEN(REPLACE(Name, ' ', '')) + 1
WHEN 2 THEN NULL
WHEN 3 THEN REVERSE(SUBSTRING(REVERSE(Name), 1, CHARINDEX(' ', REVERSE(Name)) - 1))
WHEN 4 THEN REVERSE(SUBSTRING(REVERSE(Name), 1, CHARINDEX(' ', REVERSE(Name)) - 1))
END AS Suffix
FROM names
This is not the most elegant solution, but it illustrates the usage of CHARINDEX
and SUBSTRING
that can be applied to break down a string like this. There is definitely some redundancy which could be worked out of this query and more elegant ways to implement it (plus it may not suit your dataset because of the assumptions above), but hopefully it's a helpful starting point for you.
A neater solution might be to create a function which takes 2 parameters - a string and an integer to indicate which "word" you wish to return from that string. You could then call this function from within similar CASE
logic to return the first, second, third or fourth word in the name as required.
If you need to be able to handle 3 word names of the form [First Name] [Middle Name] [Last Name]
(as I suspect you do), you'll probably want to build a list of the possible suffixes and use that list to determine whether each 3 word name has a suffix or middle name accordingly.
回答2:
SELECT
d.First_Name
,CASE WHEN 0 = CHARINDEX(' ',d.REST_OF_NAME)
THEN NULL
ELSE SUBSTRING( ---- finds the middle name from rest of the name
d.REST_OF_NAME
,1
,CHARINDEX(' ',d.REST_OF_NAME)-1
)
END AS Middle_Name
,SUBSTRING(
d.REST_OF_NAME ---- finds the Last name from rest of the name
,1 + CHARINDEX(' ', d.REST_OF_NAME)
,LEN( d.REST_OF_NAME)
) AS Last_Name
,d.Suffix
,d.CUSTOMER_NUMBER
,D.Orignal_Data_String
from
(SELECT c.Suffix,
CASE WHEN 0 = CHARINDEX(' ',c.Remainding_Name_Part)
THEN c.Remainding_Name_Part
ELSE SUBSTRING( ---- substring first name fro rest of the name from reminding part of the name
c.Remainding_Name_Part
,1
,CHARINDEX(' ',c.Remainding_Name_Part)-1
)
END AS First_Name
,CASE WHEN 0 = CHARINDEX(' ',c.Remainding_Name_Part)
THEN NULL
ELSE SUBSTRING(
c.Remainding_Name_Part
,CHARINDEX(' ',c.Remainding_Name_Part)+1 ------ substring rest of the name after substracting firstname from the remainding partof the name
,LEN(c.Remainding_Name_Part)
)
END AS REST_OF_NAME
,c.CUSTOMER_NUMBER
,C.Orignal_Data_String
FROM
(SELECT
CASE WHEN RIGHT(b.Name,2) IN ('IV','Jr','Sr')
THEN LTRIM(RTRIM(RIGHT(b.Name,2))) ----finds suffix in name
WHEN RIGHT(b.Name,3) IN ('III','Esq',' II')
THEN LTRIM(RTRIM(RIGHT(b.Name,3)))
ELSE NULL
END AS [Suffix]
,
CASE WHEN RIGHT(b.Name,2) IN ('IV','Jr','Sr')
THEN LTRIM(RTRIM(LEFT(b.name,LEN(b.name)-2))) ----finds remider part of name after subtrecting suffix
WHEN RIGHT(b.Name,3) IN ('III',' Esq',' II')
THEN LTRIM(RTRIM(LEFT(b.name,LEN(b.name)-3)))
ELSE LTRIM(RTRIM(b.name))
END AS [Remainding_Name_Part]
,B.CUSTOMER_NUMBER
,B.Orignal_Data_String
FROM
(SELECT
REPLACE(REPLACE(LTRIM(RTRIM(a.NAME)),' ',' '),' ',' ') AS [Name] ------ Clears spaces
,A.NAME AS [Orignal_Data_String]
,a.CUSTOMER_NUMBER
FROM
(
SELECT NAME,CUSTOMER_NUMBER ------ finds the customers
FROM [FIS_CORE_FEEDS_DM].[dbo].[FIS_DAILY_CUST_TABLE]
WHERE CUSTOMER_TYPE !='O'
)A
)B
)C
)D
来源:https://stackoverflow.com/questions/40619888/how-to-split-full-name-into-first-name-middle-name-last-name-and-suffix-in-tsq