1

我对 sql 很陌生,所以如果这是一个笨拙的查询,请原谅。

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

抛出错误“消息 4108,级别 15,状态 1,第 8 行窗口函数只能出现在 SELECT 或 ORDER BY 子句中。”

4

2 回答 2

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

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

于 2013-07-05T10:41:55.600 回答
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
于 2013-07-05T09:46:11.730 回答