如何在 SQL 服务器上执行文本到列
How to perform text to column on SQL Server
我有一列包含所有帐户组并由 space 分隔。我想将所有这些组拆分到每个新列中,类似于 excel 上的 'Text to Columns' 工具,它可以将单列文本拆分为多列,并为每个新的拆分列分配新的列名。我试过 charindex 但似乎有一些错误。
谢谢!
现有栏目:
Account Groups
ab bc cd cbd chjk
abc
ab bc
bc
我想要的新列:
Account1 Account2 Account3 Account4 Account5
--------------------------------------------
ab bc cd cbd chjk
abc
ab bc
bc
我使用的代码:我创建了一个函数来先分隔列。
CREATE FUNCTION dbo.newCOLUMNS
(@TEXT VARCHAR(8000),
@COLUMN TINYINT,
@SEPARATOR CHAR(1))
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE @POS_START INT = 1
DECLARE @POS_END INT = CHARINDEX(@SEPARATOR, @TEXT, @POS_START)
WHILE (@COLUMN > 1 AND @POS_END > 0)
BEGIN
SET @POS_START = @POS_END + 1
SET @POS_END = CHARINDEX(@SEPARATOR, @TEXT, @POS_START)
SET @COLUMN = @COLUMN - 1
END
IF @COLUMN > 1
SET @POS_START = LEN(@TEXT) + 1
IF @POS_END = 0
SET @POS_END = LEN(@TEXT) + 1
RETURN SUBSTRING (@TEXT, @POS_START, @POS_END - @POS_START)
END
然后我将函数放入 table:
SELECT
dbo.newCOLUMNS([Name], 1, ' ') as Account1,
dbo.newCOLUMNS([Name], 2, ' ') as Account2,
dbo.newCOLUMNS([Name], 3, ' ') as Account3,
dbo.newCOLUMNS([Name], 4, ' ') as Account4,
dbo.newCOLUMNS([Name], 5, ' ') as Account5,
dbo.newCOLUMNS([Name], 6, ' ') as Account6,
dbo.newCOLUMNS([Name], 7, ' ') as Account7,
dbo.newCOLUMNS([Name], 8, ' ') as Account8,
dbo.newCOLUMNS([Name], 9, ' ') as Account9,
dbo.newCOLUMNS([Name], 10, ' ') as Account10,
dbo.newCOLUMNS([Name], 11, ' ') as Account11
FROM
myTable;
查询只能得到 returns 部分结果,这里是错误消息:
Msg 537, Level 16, State 2, Line 1
Invalid length parameter passed to the LEFT or SUBSTRING function.
很明显,您已经吸取了教训,不要存储分隔数据。现在,如果你有一个已知的或最大的列数,那么一点点 XML 可能会有所帮助
例子
Select A.ID
,B.*
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)')
,Pos7 = xDim.value('/x[7]','varchar(max)')
,Pos8 = xDim.value('/x[8]','varchar(max)')
,Pos9 = xDim.value('/x[9]','varchar(max)')
,Pos10 = xDim.value('/x[10]','varchar(max)')
From (Select Cast('<x>' + replace([Account Groups],' ','</x><x>')+'</x>' as xml) as xDim) as A
) B
Returns
我有一列包含所有帐户组并由 space 分隔。我想将所有这些组拆分到每个新列中,类似于 excel 上的 'Text to Columns' 工具,它可以将单列文本拆分为多列,并为每个新的拆分列分配新的列名。我试过 charindex 但似乎有一些错误。
谢谢!
现有栏目:
Account Groups
ab bc cd cbd chjk
abc
ab bc
bc
我想要的新列:
Account1 Account2 Account3 Account4 Account5
--------------------------------------------
ab bc cd cbd chjk
abc
ab bc
bc
我使用的代码:我创建了一个函数来先分隔列。
CREATE FUNCTION dbo.newCOLUMNS
(@TEXT VARCHAR(8000),
@COLUMN TINYINT,
@SEPARATOR CHAR(1))
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE @POS_START INT = 1
DECLARE @POS_END INT = CHARINDEX(@SEPARATOR, @TEXT, @POS_START)
WHILE (@COLUMN > 1 AND @POS_END > 0)
BEGIN
SET @POS_START = @POS_END + 1
SET @POS_END = CHARINDEX(@SEPARATOR, @TEXT, @POS_START)
SET @COLUMN = @COLUMN - 1
END
IF @COLUMN > 1
SET @POS_START = LEN(@TEXT) + 1
IF @POS_END = 0
SET @POS_END = LEN(@TEXT) + 1
RETURN SUBSTRING (@TEXT, @POS_START, @POS_END - @POS_START)
END
然后我将函数放入 table:
SELECT
dbo.newCOLUMNS([Name], 1, ' ') as Account1,
dbo.newCOLUMNS([Name], 2, ' ') as Account2,
dbo.newCOLUMNS([Name], 3, ' ') as Account3,
dbo.newCOLUMNS([Name], 4, ' ') as Account4,
dbo.newCOLUMNS([Name], 5, ' ') as Account5,
dbo.newCOLUMNS([Name], 6, ' ') as Account6,
dbo.newCOLUMNS([Name], 7, ' ') as Account7,
dbo.newCOLUMNS([Name], 8, ' ') as Account8,
dbo.newCOLUMNS([Name], 9, ' ') as Account9,
dbo.newCOLUMNS([Name], 10, ' ') as Account10,
dbo.newCOLUMNS([Name], 11, ' ') as Account11
FROM
myTable;
查询只能得到 returns 部分结果,这里是错误消息:
Msg 537, Level 16, State 2, Line 1
Invalid length parameter passed to the LEFT or SUBSTRING function.
很明显,您已经吸取了教训,不要存储分隔数据。现在,如果你有一个已知的或最大的列数,那么一点点 XML 可能会有所帮助
例子
Select A.ID
,B.*
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)')
,Pos7 = xDim.value('/x[7]','varchar(max)')
,Pos8 = xDim.value('/x[8]','varchar(max)')
,Pos9 = xDim.value('/x[9]','varchar(max)')
,Pos10 = xDim.value('/x[10]','varchar(max)')
From (Select Cast('<x>' + replace([Account Groups],' ','</x><x>')+'</x>' as xml) as xDim) as A
) B
Returns