Создать функцию для разделения рассматриваемых строковых значений из некоторого столбца таблицы:
CREATE FUNCTION [dbo].[Fn_Splittemp]
(
@text VARCHAR(8000)
, @delimiter VARCHAR(20) = ' '
)
RETURNS @String TABLE
(
Position INT IDENTITY PRIMARY KEY
, StringValue VARCHAR(8000)
)
AS
BEGIN
DECLARE @index INT
SET @index = -1
WHILE (LEN(@text) >0)
BEGIN
SET @index = CHARINDEX(@delimiter, @text)
IF (@index = 0) AND (LEN(@text) > 0)
BEGIN
INSERT INTO @string VALUES (@text)
BREAK
END
IF (@index > 1)
BEGIN
INSERT INTO @String VALUES (LEFT(@text, (@index-1)))
SET @text = RIGHT(@text, (LEN(@text)-@index))
END
ELSE
SET @text = RIGHT(@text, (LEN(@text)-@index))
END
RETURN
END
GO
Разделение, очистка и присвоение соответствующим столбцам name_columns:
CREATE TABLE #t0 (rid INT IDENTITY, rawnames VARCHAR(8000));
GO
INSERT INTO #t0 VALUES ('JANE MIDDLETON John MIDDLETON'),
('SUE FRACARO BOB FRACARO'),
('TONY FRENCH'),
('JOHN EDUARDO OCHOA AND JANE ADRIANA OCHOA'),
('TONY JOHN CARPENTER TONYA CARPENTER');
GO
SELECT n.rid, n.rawnames, fn.StringValue AS Names,
COUNT(*) OVER(PARTITION BY rawnames) AS wordcount,
ROW_NUMBER() OVER(PARTITION BY fn.stringvalue,rawnames ORDER BY fn.stringvalue) AS LastNameids,
fn.Position
INTO #t1
FROM #t0 n
cross apply dbo.Fn_Splittemp(n.rawnames, ' ') AS fn
GO
SELECT rid, rawnames, Position AS Pid,
PersonName, LastName INTO #t2
FROM
(SELECT t.rid, t.rawnames, t.names AS Lastname, LTRIM(RTRIM(REPLACE(f.StringValue,'and',''))) AS PersonName, f.Position
FROM
(SELECT replace(sqa.rawnames,sqa.Names,sqa.Names+',') AS delimstr , sqa.*
FROM #t1 sqa
WHERE wordcount<=3 AND position = (SELECT MAX(position) from #t1 crq where crq.rid = sqa.rid)
)t
cross apply dbo.Fn_Splittemp(delimstr,',') f
UNION ALL
SELECT b.rid, b.rawnames, b.Names AS Lastname, LTRIM(RTRIM(REPLACE(f.StringValue,'and',''))) AS PersonName, f.Position
FROM
(SELECT replace(rawnames,names,names+',') AS delimstr, *
FROM #t1
WHERE wordcount>3 AND LastNameids>1)b
cross apply dbo.Fn_Splittemp(delimstr,',') f
)sqt
GO
SELECT * INTO #t3 FROM #t2 cross apply dbo.Fn_Splittemp(personname, ' ');
GO
SELECT t.rawnames, fina.Firstname, fina.MiddleName, fina.LastName
FROM #t0 t
JOIN (
SELECT rid, pid, [1] AS Firstname, NULL AS MiddleName, [2] AS LastName
FROM
(SELECT * FROM (SELECT rid, pid, position, stringvalue,
COUNT(*) OVER(PARTITION BY rid, pid) AS cnt FROM #t3)a
WHERE a.cnt <=2)apiv
PIVOT
(MAX(stringvalue)
FOR position IN ([1],[2])
)piva
UNION ALL
SELECT rid, pid, [1] AS Firstname, [2] AS MiddleName, [3] AS LastName
FROM
(SELECT * FROM (SELECT rid, pid, position, stringvalue,
COUNT(*) OVER(PARTITION BY rid, pid) AS cnt FROM #t3)a
WHERE a.cnt >2)apiv
PIVOT
(MAX(stringvalue)
FOR position IN ([1],[2],[3])
)piva
)fina
ON fina.rid = t.rid;