我需要拆分一个以管道分隔的字段('Y | N | Y | Y')。
我发现这里列出了递归函数 T-SQL: Opposite to string concatenation - how to split string into multiple records
但它会将值创建为新记录。
row field
1 Y
2 N
3 Y
4 N
我需要转换'Y | N | Y | Y'
field
'Y|N|Y|Y'
进入
field1 | field2 | field3 | field4
y N Y N
有人能指出我正确的方向吗?如果我说值的数量是固定的(它可能是在一个字段中分隔的8个值),它会更容易吗。
更新:可能的字段值可能是这个(请注意空白值): 'Y | 10 | N | 1 || Y'
答案 0 :(得分:1)
如果字段的宽度也总是固定的,即1个字符(Y / N),那么就像使用substring
函数获取所有单个字段值一样简单:
;with Data as (
select 'Y|N|Y|Y' as choices union
select 'Y|Y|Y|Y' as choices union
select 'Y|N|N|Y' as choices union
select 'Y|N|N|N' as choices union
select 'N|N|Y|N' as choices union
select 'Y|Y|N|Y' as choices
)
select
substring(choices, 1, 1) as field1,
substring(choices, 3, 1) as field2,
substring(choices, 5, 1) as field3,
substring(choices, 7, 1) as field4
from
Data
输出:
field1 field2 field3 field4
N N Y N
Y N N N
Y N N Y
Y N Y Y
Y Y N Y
Y Y Y Y
如果无法保证字段的宽度相同,则可以使用charindex
和字段索引的辅助表来生成您要查找的输出。随着字段数量的增加,这变得非常冗长,但如果要修复字段数,则只需编写一次:
;with Data as (
select 1 as id, 'Y|N|Y|Y' as choices union
select 2,'Y|Y|Y|Y' as choices union
select 3,'Y|No|N|Y' as choices union
select 4,'Yes|N|N|N' as choices union
select 5,'N|N|Yes|No' as choices union
select 6,'Y|Y|N|Yes' as choices
), Fields as (
select
id,
charindex('|', choices) as field1end,
charindex('|', choices, charindex('|', choices) + 1) as field2end,
charindex('|', choices, charindex('|', choices, charindex('|', choices) + 1) + 1) as field3end,
len(choices) + 1 as field4end
from
Data
)
select
substring(choices, 1, field1end - 1) as field1,
substring(choices, field1end + 1, field2end - field1end - 1) as field2,
substring(choices, field2end + 1, field3end - field2end - 1) as field3,
substring(choices, field3end + 1, field4end - field3end - 1) as field4
from
Data D
inner join
Fields F on D.id = F.id
输出:
field1 field2 field3 field4
Y N Y Y
Y Y Y Y
Y No N Y
Yes N N N
N N Yes No
Y Y N Yes
答案 1 :(得分:1)
**编辑:**我仍然可以使用示例字符串
这是一个替代答案,因为您知道宽度是固定长度:
DECLARE @myString AS nvarchar(20) = 'Y|10|N|1||Y'
;WITH cte
AS
(
SELECT
KeyCol = @@IDENTITY,
CONVERT(XML,'<i>' + REPLACE(@myString, '|', '</i><i>') + '</i>') AS delimited_str
)
SELECT
[1] AS Field1,
[2] AS Field2,
[3] AS Field3,
[4] AS Field4,
[5] AS Field5,
[6] AS Field6,
[7] AS Field7,
[8] AS Field8
FROM(
SELECT
KeyCol,
ROW_NUMBER() OVER (partition by KeyCol order by KeyCol)as col_nbr,
x.i.value('.', 'VARCHAR(50)') AS delimited_VAL
FROM cte
CROSS APPLY delimited_str.nodes('//i') AS x(i)
) as PivotedDataTable
PIVOT
(MAX(delimited_VAL) FOR col_nbr IN
([1], [2], [3], [4], [5], [6], [7], [8])
) AS PivotTable;
编辑:我知道在遇到类似问题之前我曾在某个地方看到过这个问题: http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/381e4164-f1e0-4b54-828f-2795d2cdcb3e/