SQL查询 - 帮助检索文本字段中的值

时间:2012-07-23 14:59:22

标签: sql sql-server-2008

我的表格如下:

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

欢迎任何想法:)

3 个答案:

答案 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

Live example at SQL Fiddle.

答案 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)>''