SQL server - 单个单元格的拆分和总和

时间:2012-09-17 15:56:09

标签: sql sql-server

我有一个nvarchar(max)类型的表格单元,通常如下所示: A03 B32 Y660 P02

e.g。一个字母后跟一个数字,用空格分隔。我想要做的是在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

显然,缺少第一个char剥离和转换为int部分,最重要的是,我得到一个“必须声明标量变量@t”错误...

2 个答案:

答案 0 :(得分: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
--@Sum has the total of cell numbers
SELECT @Sum 

答案 1 :(得分: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