SQl 服务器将分隔的字符串拆分成行
SQl Server split delimited string into rows
我在SQLServer 2008数据库中有一个table,table有两列,如下:
我想select数据如下:
这种操作在SQL服务器中比较痛苦,因为内置的字符串函数很糟糕。引用的问题使用 while
循环——这是不必要的。您可以使用递归 CTE 在一个查询中构建所有这些:
with t as (
select 'ali' as col1, 'A;B;C' as col2
),
cte as (
select col1,
convert(varchar(max), left(col2, charindex(';', col2) - 1)) as val,
convert(varchar(max), stuff(col2, 1, charindex(';', col2), '') + ';') as rest
from t
union all
select col1,
convert(varchar(max), left(rest, charindex(';', rest) - 1)) as val,
convert(varchar(max), stuff(rest, 1, charindex(';', rest), '')) as rest
from cte
where rest <> ''
)
select cte.*
from cte;
我遇到了类似的情况,我使用 XML 将其作为我的 guide 查询解决了。我对 XML 查询不是很精通,所以我对分享我的答案犹豫不决,因为即使它确实有效,我也无法逐行完整地解释它。我所理解的是,您将分隔符(或字符串)替换为关闭和打开 XML 标签,开头有一个开放标签,最后有一个关闭标签,这改变了这个...
A;B;C
进入这个...
<X>A</X>
<X>B</X>
<X>C</X>
您可以使用 XML 查询语法来检索每个节点。 "X" 除了您必须在 CROSS APPLY 部分的 nodes() 方法中使用相同的标记外,没有什么神奇的。
CREATE TABLE Table1
(
Column1 VARCHAR(20)
, Column2 VARCHAR(50)
);
INSERT INTO Table1 (Column1, Column2) VALUES ('Ali', 'A;B;C');
INSERT INTO Table1 (Column1, Column2) VALUES ('Ahmed', 'D;E');
DECLARE @Separator VARCHAR(10);
SET @Separator = ';';
SELECT a.Column1
, b.SplitData
FROM (
SELECT Column1
, CAST('<X>' + REPLACE((
SELECT Column2 AS [*] FOR XML PATH('')
)
, @Separator
, '</X><X>'
) + '</X>' AS XML) xmlfilter
FROM Table1
) AS a
CROSS APPLY (
SELECT LetterIDs.Column2.value('.', 'varchar(50)') AS SplitData
FROM a.xmlfilter.nodes('X') AS LetterIDs(Column2)
) AS b;
这里是db fiddle。希望对您有所帮助。
我在SQLServer 2008数据库中有一个table,table有两列,如下:
我想select数据如下:
这种操作在SQL服务器中比较痛苦,因为内置的字符串函数很糟糕。引用的问题使用 while
循环——这是不必要的。您可以使用递归 CTE 在一个查询中构建所有这些:
with t as (
select 'ali' as col1, 'A;B;C' as col2
),
cte as (
select col1,
convert(varchar(max), left(col2, charindex(';', col2) - 1)) as val,
convert(varchar(max), stuff(col2, 1, charindex(';', col2), '') + ';') as rest
from t
union all
select col1,
convert(varchar(max), left(rest, charindex(';', rest) - 1)) as val,
convert(varchar(max), stuff(rest, 1, charindex(';', rest), '')) as rest
from cte
where rest <> ''
)
select cte.*
from cte;
我遇到了类似的情况,我使用 XML 将其作为我的 guide 查询解决了。我对 XML 查询不是很精通,所以我对分享我的答案犹豫不决,因为即使它确实有效,我也无法逐行完整地解释它。我所理解的是,您将分隔符(或字符串)替换为关闭和打开 XML 标签,开头有一个开放标签,最后有一个关闭标签,这改变了这个...
A;B;C
进入这个...
<X>A</X>
<X>B</X>
<X>C</X>
您可以使用 XML 查询语法来检索每个节点。 "X" 除了您必须在 CROSS APPLY 部分的 nodes() 方法中使用相同的标记外,没有什么神奇的。
CREATE TABLE Table1
(
Column1 VARCHAR(20)
, Column2 VARCHAR(50)
);
INSERT INTO Table1 (Column1, Column2) VALUES ('Ali', 'A;B;C');
INSERT INTO Table1 (Column1, Column2) VALUES ('Ahmed', 'D;E');
DECLARE @Separator VARCHAR(10);
SET @Separator = ';';
SELECT a.Column1
, b.SplitData
FROM (
SELECT Column1
, CAST('<X>' + REPLACE((
SELECT Column2 AS [*] FOR XML PATH('')
)
, @Separator
, '</X><X>'
) + '</X>' AS XML) xmlfilter
FROM Table1
) AS a
CROSS APPLY (
SELECT LetterIDs.Column2.value('.', 'varchar(50)') AS SplitData
FROM a.xmlfilter.nodes('X') AS LetterIDs(Column2)
) AS b;
这里是db fiddle。希望对您有所帮助。