我的表格如下:
NAME(varchar(6), STRING(varchar(250)
ABCD '1 2 1 173 1 8 9 1 1 2 4 7 1 3.....'
APLC '1 3 11 34 1 4 99 33 23 111 12 6 7 8....'
字符串最多可包含250个字符。
我要做的是从这个字符串中获取值和各自的位置。
我知道我可以使用Charindex
,但这只能给我字符串中数字的第一个位置。
e.g。
Select Charindex ('2',STRING) where Name = ABCD
ANSWER = 7
但是我正在寻找的是类似于每个名称具有以下内容的表
Name Position Value
---------------------------
ABCD, 7, 2
ABCD, 1, 1
ABCD, 13, 1
ABCD, 18, 1
ABCD, 19, 7
欢迎任何想法:)
答案 0 :(得分:2)
在数字表的帮助下,它可能看起来像这样。
select T.Name,
N.N as Position,
substring(T.STRING, N.N, 1) as Value
from YourTable as T
cross apply Numbers as N
where N.N between 1 and 250 and
substring(T.STRING, N.N, 1) <> ' '
使用表变量和master..spt_values
作为数字表的工作示例。
declare @T table
(
NAME varchar(6),
STRING varchar(250)
)
insert into @T values
('ABCD', '1 2 1 173 1 8 9 1 1 2 4 7 1 3'),
('APLC', '1 3 11 34 1 4 99 33 23 111 12 6 7 8')
;with Numbers(N) as
(
select Number
from master..spt_values
where type = 'P'
)
select T.Name,
N.N as Position,
substring(T.STRING, N.N, 1) as Value
from @T as T
cross apply Numbers as N
where N.N between 1 and 250 and
substring(T.STRING, N.N, 1) <> ' '
答案 1 :(得分:1)
这种方法适用于多位数字。如果173
应该产生三个结果行,请检查Mikael Eriksson或podiluska的答案。
; with cte as
(
select 1 as start
, case
when patindex('%[0-9] %', string) > 0 then patindex('%[0-9] %', string)
else len(string)
end as [length]
, name
, string
from YourTable
union all
select start + [length] as start
, case
when patindex('%[0-9] %',
substring(string, start + [length], len(string)-start + [length]))
> 0 then patindex('%[0-9] %',
substring(string, start + [length], len(string)-start + [length]))
else len(string)-start + [length]
end as [length]
, name
, string
from cte
where start + [length] < len(string)
)
select Name
, start + patindex('%[0-9]%', substring(string, [start], [length])) - 1 as Position
, ltrim(substring(string, [start], [length])) as Value
from cte
答案 2 :(得分:0)
#t是你的桌子......
;WITH numbers ( n ) AS
(
select 1 as n
union all
select 1 + n FROM numbers WHERE n < 250
)
select name, n as position, SUBSTRING(string,n,1) as value
from #t, numbers
where SUBSTRING(string,n,1)<>' '
order by Name, n
option (maxrecursion 250)
另一方面,如果您想将连续数字视为一个数字......
;WITH Pieces(name, pn, start, [stop], string) AS
(
SELECT name, 1, 1, CHARINDEX(' ', string),string from #t
UNION ALL
SELECT pieces.name, pn + 1, stop + 1, CHARINDEX(' ', pieces.string, stop + 1), pieces.string
FROM Pieces
inner join #t on pieces.name = #t.name
WHERE stop > 0
)
select *
from
( SELECT name, start as position,
SUBSTRING(string, start, CASE WHEN stop > 0 THEN stop-start ELSE 300 END) AS value
FROM Pieces
) v
where RTRIM(value)>''