SQL Server 2000:有条件地从列生成和递增数据而不使用CURSOR

时间:2011-12-30 15:07:15

标签: sql sql-server sql-server-2000 cursor

:)

有没有办法创建索引,并使用给定条件递增,但没有CURSOR处理/使用

例如:

sql_tables

我的情况是:“如果当前颜色(这是要检查的项目)与最后一个相同:不增加,否则以一个单位递增”

这必须在没有CURSOR USAGE的SQL查询中,当然是个好时机(至少使用10000行)

提前致谢。

编辑:我忘了提到NEW_INDEX列不存在。必须使用查询生成它。

EDIT2:有没有办法只使用SELECT / INSERT / UPDATE语句? (未设置,声明...)

3 个答案:

答案 0 :(得分:2)

假设一个名为Colors的表格分别包含IDColorColorIndex类别的字段intvarcharint。我还假设OP表示prev / after,基于ID字段中asc字段的排序。

您可以在没有光标的情况下执行此操作,并使用while循环...但它肯定不会基于:

DECLARE @MyID int
DECLARE @CurrentIndex int
DECLARE @CurrentColor varchar(50)
DECLARE @PreviousColor varchar(50)

SET @CurrentIndex = (SELECT 0)

SET @MyID = (SELECT TOP 1 ID FROM Colors ORDER BY ID ASC)
SET @CurrentColor = (SELECT '')
SET @PreviousColor = (SELECT Color FROM Colors WHERE ID = @MyID)

WHILE (@MyID IS NOT NULL)
 BEGIN
   IF (@CurrentColor <> @PreviousColor)
     BEGIN
        SET @PreviousColor = (SELECT Color FROM Colors WHERE ID = @MyID)
        SET @CurrentIndex = (SELECT @CurrentIndex + 1)
        UPDATE Colors SET ColorIndex = @CurrentIndex WHERE ID = @MyID
     END 
   ELSE
      BEGIN
        UPDATE Colors SET ColorIndex = @CurrentIndex WHERE ID = @MyID
        SET @PreviousColor = (SELECT Color FROM Colors WHERE ID = @MyID)
      END
 SET @MyID = (SELECT TOP 1 ID FROM Colors WHERE ID > @MyID ORDER BY ID ASC)
 SET @CurrentColor = (SELECT Color FROM Colors WHERE ID = @MyID)
 END

执行后的结果:

enter image description here

只要ID和颜色被编入索引,性能就不会太糟糕。好的一面是它比使用普通的旧CURSOR要快一点,并不像它那样邪恶。解决方案支持SQL 2000,2005和2008(因为您使用的是不支持CTE的SQL 2000)。

答案 1 :(得分:2)

declare @ID int, 
        @MaxID int, 
        @NewIndex int, 
        @PrevCol varchar(50)

select @ID = min(ID),
       @MaxID = max(ID),
       @PrevCol = '',
       @NewIndex = 0       
from YourTable       

while @ID <= @MaxID
begin
  select @NewIndex = case when Colour = @PrevCol 
                       then @NewIndex 
                       else @NewIndex + 1 
                     end,
         @PrevCol = Colour
  from YourTable
  where ID = @ID

  update YourTable 
  set NewIndex = @NewIndex
  where ID = @ID

  set @ID = @ID + 1
end

http://data.stackexchange.com/stackoverflow/q/122958/

答案 2 :(得分:1)

    select
        IDENTITY(int,1,1) as COUNTER
        ,c1.ID
    into
        #temp
    from
        CUSTOMERS c1
        left outer join (
                select
                    c1.ID, max(p.ID) as PRV_ID
                from
                    CUSTOMERS c1, 
                    (
                    select
                        ID
                    from
                        CUSTOMERS
                    ) p
                where
                    c1.ID > p.ID
                group by
                    c1.ID
                    ) k on k.ID = c1.ID
        left outer join CUSTOMERS p on p.ID = k.PRV_ID 
    where        
        ((c1.FAVOURITE_COLOUR < p.FAVOURITE_COLOUR)
         or
        (c1.FAVOURITE_COLOUR > p.FAVOURITE_COLOUR)
         or
         p.FAVOURITE_COLOUR is null)

    update
        CUSTOMERS
    set
        NEW_INDEX = i.COUNTER 
    --select *
    from    
        CUSTOMERS
        inner join (
            select 
                c1.ID, max(t.COUNTER) as COUNTER
            from
                CUSTOMERS c1, 
                (
                select
                    ID
                    ,COUNTER
                from
                    #temp
                ) t
            where
                c1.ID >= t.ID
            group by
                c1.ID
            ) i on i.ID = CUSTOMERS.ID

    drop table #temp

    select * from CUSTOMERS