我在特定表的一列中有数据,其格式如下:
item1 char(1) value1 char(1) value2 char(0) item2 char(1) value3 char(1) value4 char(0)
注意:
char(0)
和char(1)
以及角色本身。也没有空格。
我需要做的是拆分原始表的列:
char(0)
char(1)
结果应该是一个包含2个列和x行的表:
column1 column2 colum3
----------------------
item1 value1 value2
item2 value3 value4
我正在写一个CLR函数来分割数据:
public partial class Functions
{
public static IEnumerable SplitData(SqlString value)
{
string[] rows = value.Value.Split('\n');
for (int i = 0, n = rows.Length; i < n; i++)
{
}
return rows;
}
}
每行都包含文本,例如:
item char(1) value1 char(1) value2
第二步是拆分每一行(这很容易)。
但是该函数如何返回上面的表,以便可以在SQL服务器中进一步处理?
答案 0 :(得分:0)
我认为实现这一目标的最简单方法是将分割功能创建为clr。在.NET中,您将可以访问具有良好性能的更好的字符串函数工具集。如果你在t-sql中执行它可能会获得更好的性能。
答案 1 :(得分:0)
测试表和数据:
DECLARE @t table(id int identity(1,1), col1 varchar(max))
insert @t values
('item'+char(1)+ 'value1'+char(1)+'value4'+char(1)+char(0)+ 'item'+char(1)+'value1'+char(1)+ 'value2'+char(1)+char(0)),
('item'+char(1)+ 'value1'+char(1)+'value2'+char(1)+char(0)+ 'item2'+char(1)+'value1'+char(1)+ 'value2'+char(1)+char(0))
查询:
;WITH SplitByRow as
(
SELECT id, t.c.value('.', 'VARCHAR(2000)') colx
FROM (
SELECT id, x = CAST('<t>' +
REPLACE(REPLACE(col1, char(1), '!new row!'), char(0), '</t><t>') + '</t>' AS XML)
FROM @t
) a
CROSS APPLY x.nodes('/t') t(c)
), SplitByColumn as
(
SELECT
id,
(row_number() over (order by (select 1))+2)/3 rowx,
(row_number() over (order by (select 1))+2)%3 colx,
t.c.value('.', 'VARCHAR(2000)') value
FROM
(
SELECT id, x = CAST('<t>' +
REPLACE(colx, '!new row!', '</t><t>') + '</t>' AS XML)
FROM SplitByRow
) a
CROSS APPLY x.nodes('/t') t(c)
WHERE t.c.value('.', 'VARCHAR(2000)') <> ''
)
SELECT
id, [0] col1,[1] col2,[2] col3
FROM
SplitByColumn
INTO
#temp
PIVOT
(min([value]) FOR colx
in([0],[1],[2])
)AS p
结果:
SELECT * FROM #temp
id col1 col2 col3
1 item value1 value4
1 item value1 value2
2 item value1 value2
2 item2 value1 value2