0

我有一个如下所示的表:

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,但这只给了我字符串中数字的第一个位置。

例如

Select Charindex ('2',STRING) where Name = ABCD

答案 = 7

但是我正在寻找的是一个表格,每个名称都有以下内容

Name  Position   Value 
---------------------------    
ABCD,   7,         2
ABCD,   1,         1
ABCD,   13,        1
ABCD,   18,        1
ABCD,   19,        7

欢迎任何想法:)

4

3 回答 3

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) <> ' '
于 2012-07-23T15:40:00.300 回答
1

This approach would work for multi-digit numbers. If 173 should result in three result rows, check Mikael Eriksson's or podiluska's answer.

; 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

Live example at SQL Fiddle.

于 2012-07-23T15:44:55.393 回答
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)>''
于 2012-07-23T15:28:12.527 回答