在SQL中将字符串列拆分为多列
我有下表:在SQL中将字符串列拆分为多列,sql,sql-server,Sql,Sql Server,我有下表: Code | Column -----+----------------------------- 152 | 12_25_62_26_65_22_88 247 | 55_56_85_52_11_45_63 369 | 45_65_25_89_52_54_96 如何编写一个SELECT查询来获得这样的结果 Code | Col1 | Col2 | Col3 | Col4 | Col5 | Col6 | Col7 -----+
Code | Column
-----+-----------------------------
152 | 12_25_62_26_65_22_88
247 | 55_56_85_52_11_45_63
369 | 45_65_25_89_52_54_96
如何编写一个SELECT查询来获得这样的结果
Code | Col1 | Col2 | Col3 | Col4 | Col5 | Col6 | Col7
-----+------+------+------+------+------+------+-------
152 | 12 | 25 | 62 | 26 | 65 | 22 | 88
247 | 55 | 56 | 85 | 52 | 11 | 45 | 63
369 | 45 | 65 | 25 | 89 | 52 | 54 | 96
你可以用这个
DECLARE @MyTable TABLE (Code INT, [Column] VARCHAR(100))
INSERT INTO @MyTable VALUES
(152 , '12_25_62_26_65_22_88'),
(247 , '55_56_85_52_11_45_63'),
(369 , '45_65_25_89_52_54_96')
SELECT Code, [1] Col1, [2] Col2, [3] Col3, [4] Col4, [5] Col5, [6] Col6, [7] Col7 FROM (
select Code, Rn, Col from (
select Code, CAST('<Root><row>' + REPLACE([Column],'_','</row><row>') + '</row></Root>' as XML) [ColumnXml] from @MyTable
) T
outer apply (select ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) RN, T.c.value( '.', 'integer') from T.[ColumnXml].nodes('/Root/row') T(c) ) ColTable(Rn, Col)
) SRC PIVOT( MAX(Col) FOR RN IN ([1],[2],[3],[4],[5],[6],[7])) PVT
我这样说:
DECLARE @mockup TABLE (Code INT, [Column] VARCHAR(100));
INSERT INTO @mockup VALUES
(152 , '12_25_62_26_65_22_88'),
(247 , '55_56_85_52_11_45_63'),
(369 , '45_65_25_89_52_54_96');
WITH Splitted AS
(
SELECT Code
,[Column]
,CAST('<x>' + REPLACE([Column],'_','</x><x>') + '</x>' AS XML) AS Parts
FROM @mockup
)
SELECT Code,[Column]
,Parts.value(N'/x[1]','int') AS Col1
,Parts.value(N'/x[2]','int') AS Col2
,Parts.value(N'/x[3]','int') AS Col3
,Parts.value(N'/x[4]','int') AS Col4
,Parts.value(N'/x[5]','int') AS Col5
,Parts.value(N'/x[6]','int') AS Col6
,Parts.value(N'/x[7]','int') AS Col7
FROM Splitted;
通过XML拆分字符串的技巧允许直接使用每个元素的位置来寻址。如果字符串包含各种类型,而不是在您的情况下,所有值都是int,那么这一点尤其有用。您可以轻松地以类型安全的方式检索所有类型
注意,这是一个糟糕的设计。如果可以更改这一点,您应该真正避免在一列中存储多个值。您可以使用动态SQL来实现这一点:
DECLARE @MyTable TABLE (Code INT, [Column] VARCHAR(100))
INSERT INTO @MyTable VALUES
(152 , '12_25_62_26_65_22_88'),
(247 , '55_56_85_52_11_45_63'),
(369 , '45_65_25_89_52_54_96')
declare @query nvarchar(1000)
set @query = ''
select @query = @query + 'select ' + cast(code as nchar(3)) + ',' + replace([column],'_',',') + ' union all ' from @MyTable
--remove last ten characters (union all statement)
set @query = left( @query, len(@query) - 10)
execute sp_executesql @query
这个问题似乎已经得到了回答:我们可以安全地假设列的数量仅限于7吗?能少一点,多一点吗?@Dakshitha你是对的,这可能是重复的,但我倾向于回答这样一个问题。在这种情况下,评分最高的答案是绝对过时的。有很好的答案,但人们倾向于选择第一个/最高的方法,所以坏的和过时的方法仍然存在……显然是圣人的方法
DECLARE @MyTable TABLE (Code INT, [Column] VARCHAR(100))
INSERT INTO @MyTable VALUES
(152 , '12_25_62_26_65_22_88'),
(247 , '55_56_85_52_11_45_63'),
(369 , '45_65_25_89_52_54_96')
declare @query nvarchar(1000)
set @query = ''
select @query = @query + 'select ' + cast(code as nchar(3)) + ',' + replace([column],'_',',') + ' union all ' from @MyTable
--remove last ten characters (union all statement)
set @query = left( @query, len(@query) - 10)
execute sp_executesql @query