在postgres表

时间:2017-03-30 05:56:23

标签: postgresql duplicates

我们有一张科学数据表,每天在全国约10,000-12,000个传感器上采样两次。每个传感器都会向我们提供一些数据,这些数据将放入此表中。

简化版本如下 - sensor_rt_data:

id | BIGINT PK
sensor-name | STRING
location-id | INT FK
sensor-value | NUMERIC(0,2)
last-updated | TIMESTAMP_WITH_TIMEZONE

不幸的是,我试图删除的全天都有重复的样本。例如

简化为(location-id last column):

2017-03-30 06:30 | 49.00 | 1
2017-03-30 06:30 | 37.00 | 2
2017-03-30 10:30 | 51.00 | 1
2017-03-30 10:30 | 35.00 | 2
2017-03-30 15:30 | 51.00 | 1
2017-03-30 15:30 | 35.00 | 2
2017-03-30 18:30 | 51.00 | 1
2017-03-30 20:30 | 42.00 | 1

试图剔除三个51,只显示1;我可以删除不同的重复项,但我不知道如何删除系列中的重复项,所以它看起来像这样:

2017-03-30 06:30 | 49.00 | 1
2017-03-30 06:30 | 37.00 | 2
2017-03-30 18:30 | 51.00 | 1
2017-03-30 15:30 | 35.00 | 2
2017-03-30 20:30 | 42.00 | 1

我也看了Deleting Duplicates on the wiki,但我的查询似乎没有删除系列数据。

在你提出建议之前,我们不能忽视源头上的重复(这很可爱,我完全感觉到了!)由于某些合法的混乱而我并不吝啬。

SQL能够处理那种重复数据删除,还是我必须将该数据移动到另一个表?我们已经运行了6个月,表大小越来越大,大部分都是不必要的ping数据。

编辑: 为了澄清,这是一个包含许多记录的大表,我试图删除复制前一个“最新”的所有重复项(但只检查某些字段 - locationid,sensor-value和last updated),如果这有意义的话。

如果这是在SQL之外完成的,我可以加载每一行(按日期ASC排序)并将每个location-id的“最新”读数存储在数组中,如果检索到的行匹配的传感器值与最后一个用于该位置ID,我会丢弃它。

最后,我应该拥有不会在时间上复制传感器值的数据,并且只存储传感器值的变化(这是相关的)。

修改

感谢下面的答案,我已经开始工作了,但是......

因此,在对查询进行一些调整之后,我已经了解了我们的数据集。但是,我注意到这些传感器读数只有两个记录......

2017-02-28 00:00:00 144
2017-02-27 00:00:00 139
2017-02-26 00:00:00 139
.. 20 more at 139
2017-02-14 00:00:00 129
...10 more at 129

变成:

2017-02-28 00:00:00 144
2017-02-14 00:00:00 129

我期待139出现在那里?该示例在接受的答案中工作得很好。

1 个答案:

答案 0 :(得分:1)

类似的东西:

delete from sensordata s
using (
  select id, 
         sensor_value = lead(sensor_value) over w as same_value_as_next
  from sensordata
  window w as (partition by location_id order by last_updated)
) x
where x.id = s.id
  and x.same_value_as_next
;

然而,由于这会越过所有行,这不会非常有效,但我现在想不出更好的方法。

在线示例:http://rextester.com/SGPOB26281