Sql Server 2005,删除和重新编号

时间:2013-07-05 09:39:12

标签: sql-server sql-server-2005

我是sql的新手,所以如果这是一个noobish查询,请原谅我。

http://i247.photobucket.com/albums/gg149/izzner/Clipboard01-1.jpg

从上图中可以看出,我在Sql DB表中有一些数据 现在我需要从我指定的序列号开始删除每4行,然后需要重新编号的Serial_no列而不改变行的顺序。

如果可能的话,我需要通过一个查询完成所有这些,但是自从过去2天以来我一直在努力

希望你们都能帮助我。 提前致谢

//USING THIS CODE TO DELETE every 4th row// 
    DELETE 
            FROM Tbl2
            FROM 
            Tbl2 AS A 
            INNER JOIN
            (
              SELECT ROW_NUMBER() OVER(ORDER BY GETDATE()) AS CNT , *
              FROM Tbl2
            ) AS B ON A.Serial_no = B.Serial_no
            WHERE CNT%4 = 0 AND CNT >= 10

然而重新编号查询(如下)

DECLARE @FIRSTID INT = 1000000010

UPDATE tbl2
SET Serial_no = @FIRSTID + ROW_NUMBER() OVER(ORDER BY Serial_no) - 1
FROM tbl2

抛出错误 “Ms 4108,Level 15,State 1,Line 8 窗口函数只能出现在SELECT或ORDER BY子句中。“

2 个答案:

答案 0 :(得分:0)

您可以通过加入查询轻松完成。做点什么

        DELETE 
        FROM tbl2
        FROM 
        tbl2 AS A 
        INNER JOIN
        (
          SELECT ROW_NUMBER() OVER(ORDER BY GETDATE()) AS CNT , *
          FROM tbl2
        ) AS B ON A.serial_no = B.serial_no
        WHERE CNT%4 = 0 AND CNT >= 10

要重新安排序列号,请使用以下查询:

        DECLARE @FIRSTID INT = 1000000001

        UPDATE tbl2
        SET serialno = @FIRSTID + ROW - 1
        FROM 
        tbl2 as a 
        inner join
        (
        SELECT * , ROW_NUMBER() OVER(ORDER BY serial_no) AS ROW
        FROM tbl2
        ) AS b on a.serial_no = b.serial_no

答案 1 :(得分:0)

我认为这个存储过程可能会起作用,我还没有完全测试它并且它没有错误处理等。第一部分删除每第4行并且游标更新序列号。您可以使用EXEC usp_update_serials 10000010来调用它,例如:

DROP PROC usp_update_serials 
GO
CREATE PROC usp_update_serials @serial INT AS 
-- delete every fourth row
WITH cte AS (
SELECT serial_no, ROW_NUMBER() OVER (ORDER BY serial_no) -1 AS rank
   FROM table1 t WHERE serial_no >= @serial
   )
DELETE cte WHERE rank%4 = 0 

-- update serial numbers
SET NOCOUNT ON
DECLARE @serial_no int, @rank int, @prev int

DECLARE serial_cursor CURSOR FOR 
SELECT serial_no, ROW_NUMBER() OVER (ORDER BY serial_no) AS rank
FROM table1 t 
OPEN serial_cursor

FETCH NEXT FROM serial_cursor 
INTO @serial_no, @rank

WHILE @@FETCH_STATUS = 0
BEGIN

SELECT @prev = t.serial_no FROM (SELECT serial_no, ROW_NUMBER() OVER (ORDER BY serial_no) AS rank
FROM TABLE1) t WHERE t.rank = @rank - 1

IF @serial_no != @prev
    BEGIN       
        UPDATE table1 SET serial_no = @prev+1 WHERE serial_no= @serial_no
    END

    FETCH NEXT FROM serial_cursor 
    INTO @serial_no, @rank
END 
CLOSE serial_cursor
DEALLOCATE serial_cursor

显然这只是一个粗略的想法,不应该用于生产......

相关问题