根据列值拆分行
Split a row based on a column value
我正在尝试根据该行单元格中的值将一行拆分为两行。
例如,我有以下 table 结构(它是一个临时 table,没有任何键、索引或任何东西,我可以 select 拆分结果在另一个临时 table 中) :
Col1 | Col2
a | one
b | two
c | three
d | one two
e | one two
那么应该拆分成:
Col1 | Col2
a | one
b | two
c | three
d | one
d | two
e | one
e | two
问题是我无法理解如何开始,我发现了这两个相似的问题,在我的情况下它是一个空字符串:
Turning a Comma Separated string into individual rows
Split values over multiple rows
您可以使用 UDF
处理字符串的拆分,并 运行 它处理每个结果。这是我很快就能完成的事情:
Create FUNCTION [dbo].[fnSplit](@text varchar(MAX), @delimiter varchar(20) = ' ')
RETURNS @Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(MAX)
)
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 @Strings VALUES (@text)
BREAK
END
IF (@index > 1)
BEGIN
INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))
SET @text = RIGHT(@text, (LEN(@text) - @index))
END
ELSE
SET @text = RIGHT(@text, (LEN(@text) - @index))
END
RETURN
END
测试数据:
Create Table #Temp
(
Col1 Varchar (20),
Col2 Varchar (20)
)
Insert #Temp
Values ('a', 'one'), ('b', 'two'), ('c', 'three'), ('d', 'one two'), ('e', 'one two')
查询:
Select Col1, Value[Col2]
From #Temp T
Cross Apply dbo.fnSplit(T.col2, ' ')
结果:
Col1 Col2
a one
b two
c three
d one
d two
e one
e two
我将使用 XML
SELECT col1,
Split.a.value('.', 'VARCHAR(100)') col2
FROM (SELECT col1,
col2,
Cast ('<M>' + Replace(col2, ' ', '</M><M>') + '</M>' AS XML) AS Data
FROM Yourtable) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
SQLFIDDLE DEMO
我正在尝试根据该行单元格中的值将一行拆分为两行。 例如,我有以下 table 结构(它是一个临时 table,没有任何键、索引或任何东西,我可以 select 拆分结果在另一个临时 table 中) :
Col1 | Col2
a | one
b | two
c | three
d | one two
e | one two
那么应该拆分成:
Col1 | Col2
a | one
b | two
c | three
d | one
d | two
e | one
e | two
问题是我无法理解如何开始,我发现了这两个相似的问题,在我的情况下它是一个空字符串:
Turning a Comma Separated string into individual rows
Split values over multiple rows
您可以使用 UDF
处理字符串的拆分,并 运行 它处理每个结果。这是我很快就能完成的事情:
Create FUNCTION [dbo].[fnSplit](@text varchar(MAX), @delimiter varchar(20) = ' ')
RETURNS @Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(MAX)
)
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 @Strings VALUES (@text)
BREAK
END
IF (@index > 1)
BEGIN
INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))
SET @text = RIGHT(@text, (LEN(@text) - @index))
END
ELSE
SET @text = RIGHT(@text, (LEN(@text) - @index))
END
RETURN
END
测试数据:
Create Table #Temp
(
Col1 Varchar (20),
Col2 Varchar (20)
)
Insert #Temp
Values ('a', 'one'), ('b', 'two'), ('c', 'three'), ('d', 'one two'), ('e', 'one two')
查询:
Select Col1, Value[Col2]
From #Temp T
Cross Apply dbo.fnSplit(T.col2, ' ')
结果:
Col1 Col2
a one
b two
c three
d one
d two
e one
e two
我将使用 XML
SELECT col1,
Split.a.value('.', 'VARCHAR(100)') col2
FROM (SELECT col1,
col2,
Cast ('<M>' + Replace(col2, ' ', '</M><M>') + '</M>' AS XML) AS Data
FROM Yourtable) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)