这不是一个理想的解决方案,并根据 OP 对另一个答案的评论做出一些猜测“这里的数据不会固定为 3 列,它可以超过 3 列” .
因此,我制作了自己的样本数据并进行了猜测。请注意,这使用了delimitedsplit8k,因此您需要它才能使用此解决方案:
USE Sandbox;
GO
CREATE TABLE dbo.StringsTable (ID int IDENTITY(1,1), --No idea if you have this, but sort order might be important
SomeString varchar(8000));
--insert sample data
INSERT INTO dbo.StringsTable (SomeString)
VALUES ('13;16;AB BC'),
('13;16;BC CD'),
('13;16;CD DE');
--Some more data, the OP says that can have strings with more (and maybe less) than 3 delimiters, but "forgot" to supply such examples...
INSERT INTO dbo.StringsTable (SomeString)
VALUES ('10'),
('19;124;BC CD;29;ZY XY'),
('29;AB CF'),
('43;BE HG;GY TY;18');
GO
SELECT *
FROM dbo.StringsTable;
GO
DECLARE @SQL nvarchar(MAX);
--Get the maximum number of parts
WITH MaxParts AS(
SELECT MAX(DS.ItemNumber) AS MaxPart
FROM dbo.StringsTable ST
CROSS APPLY dbo.DelimitedSplit8K(ST.SomeString,';') DS),
--Need a tally table now
N AS(
SELECT *
FROM (VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) V(N)),
Tally AS (
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS i
FROM N N1 --10
CROSS JOIN N N2 --100
CROSS JOIN N N3 --1000
) --If you have more than 1000 parts then repeat, but remember, delimitedSplit8K expectes a varchar(8000), not MAX
--Of course, also fee free to lower the number the tally returns, if it's not needed
SELECT @SQL =
N'SELECT ' +
STUFF((SELECT N',' + NCHAR(10) + ' MAX(CASE DS.ItemNumber WHEN ' + QUOTENAME(T.i,N'''') + N' THEN DS.Item END) AS ' + QUOTENAME('Column' + CONVERT(nvarchar(4),T.i))
FROM Tally T
WHERE T.i <= (SELECT MaxPart FROM MaxParts MP)
ORDER BY t.i
FOR XML PATH(N'')),1,9,'') + NCHAR(10) +
N'FROM dbo.StringsTable ST' + NCHAR(10) +
N' CROSS APPLY dbo.DelimitedSplit8K(ST.SomeString,'';'') DS' + NCHAR(10) +
N'GROUP BY ST.ID' + NCHAR(10) +
N'ORDER BY ST.ID;'
PRINT @SQL; --your best friend
--Run the SQL
EXEC sp_executesql @SQL;
GO
DROP TABLE dbo.StringsTable;
GO