This is a slippery slope and there are no easy answers. That said, consider the following
Declare @YourTable table (FullName varchar(50))
Insert Into @YourTable values
('Joe Bloggs'),
('Peter Smith'),
('Betty Jane Martinez'),
('Mary Jones and Liz Stone')
Select A.*
,FirstName = Pos1+case when Pos3 is not null then ' '+Pos2 else '' end
,LastName = case when Pos3 is null then Pos2 else Pos3 end
From @YourTable A
Cross Apply (
Select Pos1 = xDim.value('/x[1]','varchar(max)')
,Pos2 = xDim.value('/x[2]','varchar(max)')
,Pos3 = xDim.value('/x[3]','varchar(max)')
,Pos4 = xDim.value('/x[4]','varchar(max)')
,Pos5 = xDim.value('/x[5]','varchar(max)')
,Pos6 = xDim.value('/x[6]','varchar(max)')
From (Select Cast('<x>' + replace((Select substring(FullName,1,charindex(' and ',FullName+' and ')-1) as [*] For XML Path('')),' ','</x><x>')+'</x>' as xml) as xDim) as A
) B
Returns
FullName FirstName LastName
Joe Bloggs Joe Bloggs
Peter Smith Peter Smith
Betty Jane Martinez Betty Jane Martinez
Mary Jones and Liz Stone Mary Jones
If it helps with the visual, the CROSS APPLY generates
![enter image description here]()