9

我需要清理一个包含三列的表,ID (uniqueidentifier)、Observation (nvarchar) 和 Timestamp (datetimeoffset)。内容由两个传感器每隔 1 小时生成一次,两个传感器的 Observation 值相同。我的想法是做一个 SELECT 查询,例如

SELECT * FROM [Records] ORDER BY [Timestamp]

然后删除每个备用行。

我在 SO如何删除访问表中的每个备用行上找到了这个,但在这里并不真正适用,因为 ID 不是 Int 而是 UID。

数据样本如下所示:

在此处输入图像描述

4

4 回答 4

18

如果您使用的是 SQL Server 2005 或更高版本,则可以执行类似的操作。

delete T
from (
       select row_number() over(order by [Timestamp]) as rn
       from YourTable
       where SomeColumn = @SomeValue
     ) T
where T.rn % 2 = 0
于 2012-08-13T09:05:12.433 回答
3

除了删除备用记录之外,您还可以使用更安全的变体 - 仅删除重复的观察,以便在数据出现错误的情况下不会失去同步:

; with cte as (
  select *,
         row_number() over (partition by Observation 
                            order by [Timestamp]) rn
    from [Records]
)
delete cte
 where rn > 1
于 2012-08-13T09:09:30.080 回答
1

如果我没记错的话,您可以使用 CTE 和 row_number() 来有效地生成临时数字 id 列。然后可以应用相同的想法 - 删除行号 mod 2 为 0 的位置:

;WITH temp
     AS (SELECT *,
                Row_number() OVER (ORDER BY [Timestamp]) rn
         FROM   [Records]
         ORDER  BY [Timestamp])
DELETE FROM temp
WHERE  rn % 2 = 0
于 2012-08-13T09:05:19.893 回答
1

您可以使用 MOD 运算符将两个数字相除并返回余数

尝试

DELETE FROM [Records] WHERE ([ID] Mod 2)=0)

将其放入循环中以删除所有备用行

所以例如

ID = 0;
rows = get_number_of_rows_in_the_table;
i = 0; // counter
while(i<rows) {
ID = get the ID of row 0
if(ID MOD 2 = 0) {
//perform delete operation
DELETE FROM [Records] WHERE ID=the ID you just got;
} else { 
increment the counter 
i++
}

这是一种解决方案,但不是正确的访问语法,希望对您有所帮助

于 2012-08-13T09:10:32.740 回答