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代表一组.
这样的操作需要一些列,您可以在其上订购行以获得所需的结果.在示例中,我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子句时才能保证只获得有序结果.但您无法使用列guid或ip列来订购数据.因此,您必须在表中添加一列,以保证排序,例如递增ID或DateTime列.