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

このアプローチは、複数桁の数字に対して機能します。1733 つの結果行が必要な場合は、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

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)

一方、連続する番号を1つの番号として扱いたい場合は...

;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 に答える