删除Postgres中的重复项

时间:2016-03-11 22:13:11

标签: sql postgresql duplicates

使用Postgres 9.5,我有一个表properties

CREATE TABLE properties (
    id serial PRIMARY KEY,
    property_id integer,
    state character(2),
    record_type character(1),
    ...
);
  • id是我唯一的内部身份证明。
  • property_id来自第三方。来自不同州的属性可以共享相同的property_id,但每个州只有一个property_id。原因是,properties表包含所有状态,而不是每个表一个状态,property_id计数器从每个状态的1开始。
  • state是美国州名缩写(例如MA,CA,NY)。当与property_id连接时,它引用一个属性,例如12345NY
  • record_type可以是A(添加),C(更改)或D(删除)。

将新属性添加到表后,其record_typeA。随着时间的推移,一个属性'详细信息已更改,并且表中添加了C作为record_type的新行。

示例:

id,   property_id, state, record_type, ...
7353, 6001,        'MA',  'A',         ...
7354, 6001,        'MA',  'C',         ...
7355, 6001,        'MA',  'C',         ...

以下是问题:我想只保留属性的最新行(不管record_type是什么)并删除所有旧版本。所以在这个例子中,只需保留最后一行。没有日期列,但我们可以假设id越高,记录越新。作为旁注,以前已删除包含D记录类型的所有行,因此我们只处理addchange记录类型。

2 个答案:

答案 0 :(得分:2)

WITH CTE AS
  (SELECT *,ROW_NUMBER() OVER(PARTITION by property_id,state
                              ORDER BY id DESC) AS rn
   FROM properties)
DELETE
FROM properties WHERE id IN (SELECT id FROM CTE WHERE rn >1)

答案 1 :(得分:1)

如果您只想保留每property_id state对的一条记录,无论其他字段如何,这都应该足够了

DELETE FROM properties p1 
WHERE p1.id != 
(SELECT max(p2.id) FROM properties p2 WHERE 
 p2.property_id = p1.property_id AND p2.state = p1.state);