2012-09-17 76 views
0

我有類型爲nvarchar(最大)的一個表格單元格的拆分和總和通常看起來像這樣: A03 B32 Y660 P02SQL服務器 - 單細胞

例如一個字母后跟一個數字,用空格分隔。我想要做的是在SQL過程中獲得所有這些數字的總和。其他語言中的東西相當簡單,但我對SQL相當陌生,而且在我看來,像在字符串中使用相當笨拙的語言。 Aaanyway,我想這將是這樣的:

1)創建一個臨時表和使用分流功能

2)剝去每一個細胞

3的第一個字符)轉換數據填充以int

4)更新目標table.column設置爲所述臨時表的總和。

所以我得到儘可能的:

CREATE PROCEDURE [dbo].[SumCell] @delimited nvarchar(max), @row int 
AS 
BEGIN 
declare @t table(data nvarchar(max)) 

declare @xml xml 
set @xml = N'<root><r>' + replace(@delimited,' ','</r><r>') + '</r></root>' 

insert into @t(data) 
select 
    r.value('.','varchar(5)') as item 
from @xml.nodes('//root/r') as records(r) 

UPDATE TargetTable 
SET TargetCell = SUM(@t.data) WHERE id = @row 
END 

顯然,第一個字符剝離並轉換爲int部分缺失以及最重要的是,我得到一個「必須聲明標量變量@t」錯誤...

回答

1

問題不是很清楚,所以假設您的文本是在單個單元格中,如A3 B32 Y660 P20以下代碼段可用於獲取總和。

DECLARE @Cell NVARCHAR(400), @Sum INT, @CharIndex INT 

SELECT @Cell = 'A3 B32 Y660 P20',@Sum=0 

WHILE (LEN(LTRIM(@Cell))>0) 
BEGIN 
    SELECT @CharIndex = CHARINDEX(' ',@Cell,0) 

    SELECT @Sum = @Sum + 
     SUBSTRING(@Cell,2,CASE WHEN @CharIndex>2 THEN @CharIndex-2 ELSE LEN(@Cell)-1 END) 

    SELECT @Cell = SUBSTRING(@Cell,@CharIndex+1,LEN(@Cell)) 

    IF NOT (@CharIndex >0) BREAK; 
END 
[email protected] has the total of cell numbers 
SELECT @Sum 
0

我假設您確實希望能夠在您的分隔列表中找到完整選擇表格的值的總和。因此,我相信你問題中最複雜的部分是分裂值。我傾向於使用該方法需要一個數字表,所以我會與開始:

--If you really want to use a temporary numbers table don't use this method! 
create table #numbers(
    Number int identity(1,1) primary key 
) 
declare @counter int 
set @counter = 1 
while @counter<=10000 
begin 
    insert into #numbers default values 
    set @counter = @counter + 1 
end 

我還會創建一些測試數據

create table #data(
    id int identity(1,1), 
    cell nvarchar(max) 
) 
insert into #data(cell) values('A03 B32 Y660 P02') 
insert into #data(cell) values('Y72 A12 P220 B42') 

然後,我把拆分功能進入CTE保持乾淨:

;with split as (
    select d.id, 
     [valOrder] = row_number() over(partition by d.cell order by n.Number), 
     [fullVal] = substring(d.cell, n.Number, charindex(' ',d.cell+' ',n.Number) - n.Number), 
     [char] = substring(d.cell, n.Number, 1), 
     [numStr] = substring(d.cell, n.Number+1, charindex(' ',d.cell+' ',n.Number) - n.Number) 
    from #data d 
     join #numbers n on substring(' '+d.cell, n.Number, 1) = ' ' 
    where n.Number <= len(d.cell)+1 
) 
select id, sum(cast(numStr as int)) 
from split 
group by id