答案 0 :(得分:0)
一些免责声明:
STRING_SPLIT
需要SQL Server 2016 + MAXDOP 1
故意添加SQL:
-- seeding data
DECLARE @data TABLE ([Name] VARCHAR(50), Column1 VARCHAR(50), Column2 VARCHAR(50), Column3 VARCHAR(50))
INSERT @data VALUES ('Prod1', '3,5,6,9', '33,44,66,7', '66,7')
-- splitting strings into coluns
;WITH cte_col1 AS (
SELECT Name,
Col1.value AS ColumnValue,
ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS rn,
1 AS ColumnID
FROM @data d
CROSS APPLY STRING_SPLIT(d.Column1, ',') AS Col1
)
, cte_col2 AS (
SELECT Name,
Col2.value AS ColumnValue,
ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS rn,
2 AS ColumnID
FROM @data d
CROSS APPLY STRING_SPLIT(d.Column2, ',') AS Col2
)
, cte_col3 AS (
SELECT Name,
Col3.value AS ColumnValue,
ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS rn,
3 AS ColumnID
FROM @data d
CROSS APPLY STRING_SPLIT(d.Column3, ',') AS Col3
)
-- gluing all parts together
SELECT
d.Name
, min (CASE WHEN d.ColumnID = 1 THEN d.ColumnValue END ) AS Column1
, min (CASE WHEN d.ColumnID = 2 THEN d.ColumnValue END ) AS Column2
, min (CASE WHEN d.ColumnID = 3 THEN d.ColumnValue END ) AS Column3
FROM (
SELECT Name, ColumnValue, rn, cte_col1.ColumnID FROM cte_col1
UNION ALL
SELECT Name, ColumnValue, rn, cte_col2.ColumnID FROM cte_col2
UNION ALL
SELECT Name, ColumnValue, rn, cte_col3.ColumnID FROM cte_col3
) d
GROUP BY d.Name, d.rn
ORDER BY d.Name, d.rn
OPTION (MAXDOP 1)
结果为:
Name Column1 Column2 Column3
Prod1 3 33 66
Prod1 5 44 7
Prod1 6 66 NULL
Prod1 9 7 NULL
答案 1 :(得分:0)
不幸的是,SPLIT_STRING()
没有“常规”或“索引”选项。因此,您不能真正以已知顺序检索值。 (实际上,它会按顺序返回值,但不能保证。)
而且,SQL表和结果集是无序的。因此,即使代码似乎正常工作,也要依赖于排序是一个非常糟糕的做法。
我建议使用递归CTE:
with t as (
select 'prod1' as name, '3,5,6,9' as col1, '33,44,66,7' as col2, '66,7' as col3
),
cte as (
select name, 1 as lev,
convert(varchar(max), left(col1, charindex(',', col1 + ',') - 1)) as col1,
convert(varchar(max), stuff(col1, 1, charindex(',', col1 + ','), '')) as col1_rest,
convert(varchar(max), left(col2, charindex(',', col2 + ',') - 1)) as col2,
convert(varchar(max), stuff(col2, 1, charindex(',', col2 + ','), '')) as col2_rest,
convert(varchar(max), left(col3, charindex(',', col3 + ',') - 1)) as col3,
convert(varchar(max), stuff(col3, 1, charindex(',', col3 + ','), '')) as col3_rest
from t
union all
select name, lev + 1,
left(col1_rest, charindex(',', col1_rest + ',') - 1) as col1,
stuff(col1_rest, 1, charindex(',', col1_rest + ','), '') as col1_rest,
left(col2_rest, charindex(',', col2_rest + ',') - 1) as col2,
stuff(col2_rest, 1, charindex(',', col2_rest + ','), '') as col2_rest,
left(col3_rest, charindex(',', col3_rest + ',') - 1) as col3,
stuff(col3_rest, 1, charindex(',', col3_rest + ','), '') as col3_rest
from cte
where col1_rest <> '' or col2_rest <> '' or col3_rest <> ''
)
select name, col1, col2, col3
from cte;
Here是db <>小提琴。