sql用于在中间计数null并插入数字

时间:2014-08-19 04:59:26

标签: sql oracle oracle11g

我有一个列c1的表。我需要这样的c2:

    C1        C2
(somevalue)   3
(somevalue)   3
   NULL       3 
(somevalue)   2
   NULL       2
(somevalue)   3
   NULL       3
   NULL       3
(somevalue)   2
   NULL       2
(somevalue)   1

逻辑:计算非空的行,直到找到空后跟一个非空值,包括空值,但没有以下值。当超过null时再次开始计数,直到找到下一个空值。

2 个答案:

答案 0 :(得分:2)

以下是原始问题的答案,其中OP想要计算NULL值。

    C1        C2
   NULL       3
   NULL       3 
(somevalue)   3
   NULL       4
   NULL       4
   NULL       4
(somevalue)   4
   NULL       2
(somevalue)   2

假设列要按id列排序,这可能是您想要的:

select id, c1, x, y,
    count(1) over (partition by y) z
from(
    select id, c1, x,
        LAG(x,1,x) over (order by id) y
    from (
        select 
            id, 
            c1, 
            count(c1) over (order by id) x 
        from test
    )
)
order by id;

当然,您可以从最外面的select语句中删除多余的列。

There is a Sql Fiddle for it.

当前版本的答案可以通过将答案中的C1替换为解码(c1,null,' x',null)以及可能对边界案例进行一些小调整来获得。

答案 1 :(得分:0)

这是另一种使用游标的方法(假设表由id列排序):

    declare @id int, @C1 varchar(15), @C2 int, @counter int
    select @counter = 0
    DECLARE cursor1 CURSOR FOR             
            SELECT id, C1, C2 FROM tableName order by id
    OPEN cursor1;
    FETCH NEXT FROM cursor1 INTO @id, @C1, @C2;

    WHILE @@FETCH_STATUS = 0
    BEGIN

        if (@C1 is NULL)
            select @counter = @counter + 1
        else
        begin
            select @counter = @counter + 1
            update tableName set C2 = @counter where id = @id 
            select @id, @C1, @C2, @counter
            select @counter = 0 
        end

        FETCH NEXT FROM cursor1 INTO @id, @C1, @C2;   
    END
    CLOSE cursor1;
    DEALLOCATE cursor1;

快乐的编码!