除了这个事实,这是不好的设计,这里是一个解决方案:
就在这个粘贴到一个空的查询窗口,然后执行。适应您的需求...
declare @tbl TABLE(Column1 VARCHAR(15),Column2 VARCHAR(15),Column3 VARCHAR(150));
INSERT INTO @tbl VALUES
('ABC','123','User7;User9')
,('nbm','qre','User1;User2;User3')
,('POI','kjh','User1;User4;User5;User9');
WITH Splitted AS
(
SELECT Column1,Column2,CAST('<x>'+REPLACE(Column3,';','</x><x>')+'</x>' AS XML) AS Col3Splitted
FROM @tbl
)
SELECT Column1,Column2,Col3Splitted
,Col3Splitted.value('x[1]','varchar(max)') AS Column4
,Col3Splitted.value('x[2]','varchar(max)') AS Column5
,Col3Splitted.value('x[3]','varchar(max)') AS Column6
,Col3Splitted.value('x[4]','varchar(max)') AS Column7
/*Add as many as you need*/
FROM Splitted
在与@SeanLang的讨论后,我添加这种动态的方法。它将计算Column3中分号的最高数量,并动态构建上面的语句。
CREATE TABLE #tbl (Column1 VARCHAR(15),Column2 VARCHAR(15),Column3 VARCHAR(150));
INSERT INTO #tbl VALUES
('ABC','123','User7;User9')
,('nbm','qre','User1;User2;User3')
,('POI','kjh','User1;User4;User5;User9');
DECLARE @sql VARCHAR(MAX)=
'WITH Splitted AS
(
SELECT Column1,Column2,CAST(''<x>''+REPLACE(Column3,'';'',''</x><x>'')+''</x>'' AS XML) AS Col3Splitted
FROM #tbl
)
SELECT Column1,Column2';
DECLARE @counter INT = 0;
WHILE @counter<=(SELECT MAX(LEN(Column3) - LEN(REPLACE(Column3, ';', ''))) from #tbl)
BEGIN
SET @[email protected]+1;
SET @[email protected]+',Col3Splitted.value(''x[' + CAST(@counter AS VARCHAR(10)) + ']'',''varchar(max)'') AS Column' + CAST(@counter+3 AS VARCHAR(10));
END
SET @[email protected]+ ' FROM Splitted;';
EXEC (@sql);
DROP TABLE #tbl;
是否有你需要在同一个表中的用户的原因?为什么不把它们分离到另一个表中,然后创建一个链接表来加入它们?这样你就不用太担心会有多少用户...... –
你实际上是想修改包含数据的表结构还是仅仅用于显示目的? – DeanOC
您遇到问题的原因是因为您的数据未正确归一化。您首先必须将该分隔列表拆分为可用的东西。然后,您将需要一个动态交叉表或数据透视表来生成您所需的动态列。 –