有条件地从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...
的副本
我想从列 '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...
的副本