有条件地从postgres中的数据库中删除重复项

conditionally remove duplicates from database in postgres

我想从列 'value' 中删除重复项,但前提是与上次更新相比没有变化。我阅读了有关滞后和超前的教程,但找不到删除重复项的示例。

原文:

+----+-------+-------+------------------------+
| ID | subID | value |       updated_at       |
+----+-------+-------+------------------------+
|  1 |     2 | 2.20  | 2020-02-16 07:36:25+01 |
|  1 |     2 | 2.20  | 2020-02-16 07:31:25+01 |
|  1 |     2 | 2.20  | 2020-02-16 07:26:25+01 |
|  1 |     2 | 2.30  | 2020-02-16 07:21:25+01 |
|  1 |     2 | 2.20  | 2020-02-16 07:16:25+01 |
|  1 |     2 | 2.20  | 2020-02-16 07:11:25+01 |
+----+-------+-------+------------------------+

期望的输出:

+----+-------+-------+------------------------+
| ID | subID | value |       updated_at       |
+----+-------+-------+------------------------+
|  1 |     2 | 2.20  | 2020-02-16 07:36:25+01 |
|  1 |     2 | 2.30  | 2020-02-16 07:21:25+01 |
|  1 |     2 | 2.20  | 2020-02-16 07:16:25+01 | 
+----+-------+-------+------------------------+

这是一个空岛问题。如果你想要 earch 值更改前的最后一行,你可以使用 lead():

select *
from (
    select 
        t.*, 
        lead(value) over(partition by id, sub_id order by updated_at) next_value
    from mytable t
) t
where value <> next_value or next_value is null

另一方面,如果您想要在每次值更改后获得第一个值,则可以使用 lag() 而不是 lead()(查询的其余部分应保持不变)。

我会使用滞后或领先并通过 ctid 删除:

DELETE FROM yourtable WHERE ctid IN
(
  SELECT
    ctid
  FROM 
  (
    SELECT 
      ctid,
      value,
      LAG(value) OVER(PARTITION BY id, subid ORDER BY updated_at) pre
    FROM 
      yourtable t
  ) t
  WHERE value = pre 
)

与来自 Internet 的任何删除查询一样,运行 它针对 table...

的副本