在SQL中使用单个游标比较两行

时间:2013-03-02 06:35:08

标签: sql cursor cursor-position

我有下表

+-------+-------+----------+------+
| icode | iname | icatcode | slno |
+-------+-------+----------+------+
|    10 | a     |       11 |    0 |
|    20 | b     |       31 |    0 |
|    30 | c     |       11 |    0 |
|    40 | d     |       21 |    0 |
|    50 | e     |       31 |    0 |
|    60 | f     |       11 |    0 |
|    70 | g     |       21 |    0 |
|    80 | h     |       41 |    0 |
+-------+-------+----------+------+

我需要使用游标更新 slno 列。 o / p应该是下表,即,当 icatcode 相同时,它应该增加 slno ,当 icatcode 更改时,它应该设置 slno 为1。

+-------+-------+----------+------+
| icode | iname | icatcode | slno |
+-------+-------+----------+------+
|    10 | a     |       11 |    1 |
|    30 | b     |       11 |    2 |
|    60 | c     |       11 |    3 |
|    70 | d     |       21 |    1 |
|    40 | e     |       21 |    2 |
|    50 | f     |       31 |    1 |
|    20 | g     |       31 |    2 |
|    80 | h     |       41 |    1 |
+-------+-------+----------+------+

我已经为它编写了查询

declare @icode int,@iccode int,@islno int,@inccode int

set @islno=1

declare cur2 cursor for select icode,iccode from im order by iccode

open cur2

fetch next from cur2 into @icode,@iccode

while @@FETCH_STATUS=0

begin

    update im  set slno=@islno where @icode=icode
    fetch next from cur2 into @icode,@inccode
    if @iccode<>@inccode
    begin
    set @islno=1
    end
    else
    begin
    set @islno=@islno+
    end

end

close cur2
deallocate cur2

以上查询结果如下o / p

+-------+-------+----------+------+
| icode | iname | icatcode | slno |
+-------+-------+----------+------+
|    10 | a     |       11 |    1 |
|    20 | b     |       31 |    1 |
|    30 | c     |       11 |    2 |
|    40 | d     |       21 |    1 |
|    50 | e     |       31 |    1 |
|    60 | f     |       11 |    3 |
|    70 | g     |       21 |    1 |
|    80 | h     |       41 |    1 |
+-------+-------+----------+------+

我需要做哪些更改才能获得所需的o / p?我只需要使用游标就可以做到这一点。

1 个答案:

答案 0 :(得分:0)

在SQLServer中,您可以尝试这个

DECLARE @icode int,
        @icatcodeOld int,
        @icatcode int,
        @slno int = 1                   

DECLARE cur2 CURSOR
  FOR
    SELECT icode, icatcode
    FROM im    
    ORDER BY icatcode ASC        
  OPEN cur2
  FETCH NEXT FROM cur2 INTO @icode, @icatcode
  WHILE @@FETCH_STATUS = 0
    BEGIN      
      UPDATE im
      SET slno = @slno                  
      WHERE icode = @icode                 

      SET @icatcodeOld = @icatcode                                                             
      FETCH NEXT FROM cur2 INTO @icode, @icatcode      
      SELECT @slno = CASE WHEN @icatcodeOld = @icatcode THEN @slno + 1 ELSE 1 END
    END

  CLOSE cur2
  DEALLOCATE cur2

SQLFiddle上的演示