Reputation: 854
I am looking to split middle name from first name, only if first name has space and after space also it should be 1 character, if it has more than 1 character we should consider whole string as firstname.
For example: input string is "MATE K" then it should be split into two part,
Firstname = MATE & MiddleInitial = K
BUT if input string is "MATE KATE" then it should not split and keep it as it is.
Firstname = MATE KATE
Here is example which I did work, but it does not give me output as expected.
Can someone please help me?
declare @name as varchar(50)
set @name ='MATE KATE'
select left(@name, CHARINDEX(' ', @name)) as FirstName,
substring(@name, CHARINDEX(' ', @name) +1, len(@name)-(CHARINDEX(' ',@name)-1)) as MiddleInitial
Upvotes: 2
Views: 2468
Reputation: 15977
With the help of XML:
DECLARE @name varchar(50),
@xml xml
SET @name ='Mate Kate'
SELECT @xml = CAST('<f><n>' + REPLACE(@name,' ','</n><n>') + '</n></f>' as xml)
;WITH cte AS (
SELECT t.v.value('.','nvarchar(50)') as Names,
CASE WHEN LEN(t.v.value('.','nvarchar(50)')) = 1 THEN 1 ELSE 0 END as LenName,
row_number() over(order by t.v) as RowNumber
FROM @xml.nodes('/f/n') as t(v)
WHERE NULLIF(t.v.value('.','nvarchar(50)'),'') IS NOT NULL
)
SELECT
STUFF(
(SELECT ' ' + NAMES
FROM cte
WHERE LenName = 0 OR (LenName = 1 and RowNumber = 1)
FOR XML PATH('')),1,1,'') as FirstName,
STUFF(
(SELECT ' ' + NAMES
FROM cte
WHERE LenName = 1 AND RowNumber != 1
FOR XML PATH('')),1,1,'') as MiddleInitial
For 'Mate Kate'
or ' Mate Kate '
FirstName MiddleInitial
Mate Kate NULL
For 'Mate K'
or 'Mate K '
FirstName MiddleInitial
Mate K
For ' M Kate '
or 'M Kate'
FirstName MiddleInitial
M Kate NULL
Upvotes: 0
Reputation: 1044
Hope this helps.
declare @name as varchar(50)
set @name ='MATE K'
select CASE WHEN CHARINDEX(' ',REVERSE(LTRIM(RTRIM(@name))),0)=2 THEN left(LTRIM(RTRIM(@name)), CHARINDEX(' ', LTRIM(RTRIM(@name)))) ELSE LTRIM(RTRIM(@name)) END AS firstname,
CASE WHEN CHARINDEX(' ',REVERSE(LTRIM(RTRIM(@name))),0)=2 THEN LTRIM(RTRIM(substring(LTRIM(RTRIM(@name)), CHARINDEX(' ', LTRIM(RTRIM(@name))) +1, len(LTRIM(RTRIM(@name)))-(CHARINDEX(' ',LTRIM(RTRIM(@name)))-1)))) ELSE '' END as MiddleInitial
Upvotes: 0
Reputation: 8865
DECLARE @t table
(name varchar(20))
INSERT INTO @t(name) values
('MATE K'),
('MATE KATE')
select
CASE WHEN LEN(substring(name, CHARINDEX(' ', name) +1, len(name)-(CHARINDEX(' ',name)-1))) > 1
THEN
NAME
ELSE left(name, CHARINDEX(' ', name)) END as FirstName,
CASE WHEN LEN(substring(name, CHARINDEX(' ', name) +1, len(name)-(CHARINDEX(' ',name)-1))) = 1
THEN
substring(name, CHARINDEX(' ', name) +1, len(name)-(CHARINDEX(' ',name)-1)) ELSE NULL END as MiddleInitial
FROM @t
Upvotes: 0
Reputation: 22733
This should do the job, could probably be simplified though:
DECLARE @name AS VARCHAR(50)
SET @name = 'MATE K'
SELECT CASE WHEN CHARINDEX(' ', @name) != LEN(@name) - 1 THEN @name
ELSE LEFT(@name, CHARINDEX(' ', @name))
END AS FirstName ,
CASE WHEN CHARINDEX(' ', @name) = LEN(@name) - 1
THEN SUBSTRING(@name, CHARINDEX(' ', @name) + 1, 1)
ELSE ''
END AS MiddleName
Output:
FirstName MiddleName
MATE K
SET @name = 'MATE KATE'
SELECT CASE WHEN CHARINDEX(' ', @name) != LEN(@name) - 1 THEN @name
ELSE LEFT(@name, CHARINDEX(' ', @name))
END AS FirstName ,
CASE WHEN CHARINDEX(' ', @name) = LEN(@name) - 1
THEN SUBSTRING(@name, CHARINDEX(' ', @name) + 1, 1)
ELSE ''
END AS MiddleName
-- Output:
Output:
FirstName MiddleName
MATE KATE
Upvotes: 0
Reputation: 35780
This will not consider all possible bad strings, but will give you a start point. And you better do this not in SQL
but with some CLR
. SQL
is not really supposed to do things like this and is quite limited:
DECLARE @t TABLE ( s VARCHAR(MAX) )
INSERT INTO @t
VALUES ( 'MATE K' ),
( 'MATE KATE' )
SELECT SUBSTRING(s, 1,
CASE WHEN SUBSTRING(REVERSE(s), 2, 1) = ' '
THEN CHARINDEX(' ', s) - 1
ELSE LEN(s)
END) AS FirstName ,
CASE WHEN SUBSTRING(REVERSE(s), 2, 1) = ' '
THEN SUBSTRING(s, LEN(s), 1)
ELSE NULL
END AS MiddleName
FROM @t
Output:
FirstName MiddleName
MATE K
MATE KATE NULL
Upvotes: 3