复制上一行的行数据

Vip*_*mar 1 sql t-sql sql-server

我有一张如下表:

????????????????????????????????????????????????????????????????
?                  Id                  ? ContiguousSubnetStart ?
????????????????????????????????????????????????????????????????
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 10.60.66.8            ?
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 1                     ?
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 10.60.66.18           ?
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 1                     ?
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 1                     ?
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 1                     ?
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 1                     ?
? B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7 ? 10.60.88.28           ?
? B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7 ? 1                     ?
? B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7 ? 1                     ?
? B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7 ? 1                     ?
????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

我希望这个表转换成:

????????????????????????????????????????????????????????????????
?                  Id                  ? ContiguousSubnetStart ?
????????????????????????????????????????????????????????????????
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 10.60.66.8            ?
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 10.60.66.8            ?
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 10.60.66.18           ?
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 10.60.66.18           ?
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 10.60.66.18           ?
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 10.60.66.18           ?
? 53DC370E-8C7D-4526-9292-35125443E4B1 ? 10.60.66.18           ?
? B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7 ? 10.60.88.28           ?
? B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7 ? 10.60.88.28           ?
? B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7 ? 10.60.88.28           ?
? B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7 ? 10.60.88.28           ?
????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

不使用游标.ip-address 其次是1代表一组.

Gio*_*uri 6

这样的操作需要一些列,您可以在其上订购行以获得所需的结果.在示例中,我rn使用窗口函数手动添加了这样一个列row_number:

DECLARE @t TABLE
    (
      Id UNIQUEIDENTIFIER ,
      ContiguousSubnetStart VARCHAR(100)
    )

INSERT  INTO @t
VALUES  ( '53DC370E-8C7D-4526-9292-35125443E4B1', '10.60.66.8' ),
        ( '53DC370E-8C7D-4526-9292-35125443E4B1', '1' ),
        ( '53DC370E-8C7D-4526-9292-35125443E4B1', '10.60.66.18' ),
        ( '53DC370E-8C7D-4526-9292-35125443E4B1', '1' ),
        ( '53DC370E-8C7D-4526-9292-35125443E4B1', '1' ),
        ( '53DC370E-8C7D-4526-9292-35125443E4B1', '1' ),
        ( '53DC370E-8C7D-4526-9292-35125443E4B1', '1' ),
        ( 'B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7', '10.60.88.28' ),
        ( 'B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7', '1' ),
        ( 'B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7', '1' ),
        ( 'B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7', '1' )


;WITH cte AS(SELECT *, ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) rn FROM @t)
SELECT oa.Id, oa.ContiguousSubnetStart 
FROM cte t1
OUTER APPLY(SELECT TOP 1 * 
            FROM cte t2 
            WHERE t1.Id = t2.Id AND t2.ContiguousSubnetStart <> '1' AND t2.rn <= t1.rn 
            ORDER BY rn DESC)oa
Run Code Online (Sandbox Code Playgroud)

如果您选择,cte您将看到:

Id                                      ContiguousSubnetStart   rn
53DC370E-8C7D-4526-9292-35125443E4B1    10.60.66.8              1
53DC370E-8C7D-4526-9292-35125443E4B1    1                       2
53DC370E-8C7D-4526-9292-35125443E4B1    10.60.66.18             3
53DC370E-8C7D-4526-9292-35125443E4B1    1                       4
53DC370E-8C7D-4526-9292-35125443E4B1    1                       5
53DC370E-8C7D-4526-9292-35125443E4B1    1                       6
53DC370E-8C7D-4526-9292-35125443E4B1    1                       7
B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7    10.60.88.28             8
B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7    1                       9
B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7    1                       10
B6F8484C-B8F9-4CB0-B6BF-395A7599FFB7    1                       11
Run Code Online (Sandbox Code Playgroud)

如果您有一个像递增标识或日期列这样的列,您可以使用该列明确地对表中的数据进行排序,而不是使用该列rn,您将不再需要cte.假设列名是SomeOrderingColumn,那么您的语句将如下所示:

SELECT oa.Id, oa.ContiguousSubnetStart 
FROM TableName t1
OUTER APPLY(SELECT TOP 1 * 
            FROM TableName t2 
            WHERE t1.Id = t2.Id AND t2.ContiguousSubnetStart <> '1' 
                  AND t2.SomeOrderingColumn <= t1.SomeOrderingColumn
            ORDER BY SomeOrderingColumn DESC)oa
Run Code Online (Sandbox Code Playgroud)

如果没有该排序列,您仍然可以获得所需的结果,但在任何情况下都不会保证,并且您可能会在某一天遇到错误的结果.这已被多次讨论,您可以发现只有在明确使用ORDER BY子句时才能保证只获得有序结果.但您无法使用列guidip列来订购数据.因此,您必须在表中添加一列,以保证排序,例如递增IDDateTime列.