2012-07-23 32 views
0

值的檢索我有一個表,看起來像如下:SQL查詢 - 幫助需要在文本字段

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 

ANSWER = 7

但是我正在尋找的是類似的表已經中下面的每個名稱

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

任何想法表示歡迎:)

+2

歡迎StackOverflow上:如果您發佈的代碼,XML或數據樣本,** **請在高亮文本編輯器的線,然後單擊「代碼示例」按鈕('{} ')在編輯器工具欄上進行恰當的格式化和語法突出顯示! – 2012-07-23 15:01:59

+1

**什麼**數據庫系統,以及哪個版本? * SQL *只是*結構化查詢語言* - 許多數據庫系統使用的語言,但不是數據庫產品...字符串操作等功能通常是特定於供應商的 - 所以我們真的需要知道什麼**數據庫系統* *您正在使用...... – 2012-07-23 15:02:43

+1

@marc_s +100耐心和意願,以糾正新成員。 :-) – 2012-07-23 15:04:53

回答

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) <> ' ' 
+0

他的方法只適用於單位數字,對嗎? – Andomar 2012-07-23 15:40:22

+0

是的,我認爲這是OP想要的。 – 2012-07-23 15:40:57

+0

@Mikael Eriksson 非常感謝這個解決方案的完美工作! – user1546143 2012-07-24 06:19:12

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)>'' 
+0

這種方法僅適用於單位數字,對嗎? – Andomar 2012-07-23 15:39:24

+0

@Andomar是的。我原本有一個工作的數字序列(見編輯歷史),但後來我重新讀了這個問題,並從示例集,單個數字是請求。 – podiluska 2012-07-23 15:41:20

+0

Thx很多所有的反饋傢伙!非常感謝,生病嘗試你的解決方案並提供反饋。來自非洲的問候 – user1546143 2012-07-23 18:16:22

1

該方法適用於多位數字。如果173應導致三個結果行,請檢查Mikael Eriksson's或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.