Postgres添加seq#来区分数据库中的唯一行

时间:2009-07-28 17:55:38

标签: postgresql

在现有的应用程序中,我有一个没有主键的表,其中(很少)有重复的行。为了与另一个系统集成,我需要在表中添加一列,使这些重复行唯一。该表基本上是:

+------+---------+--------+
| txn# | detail# | amount |
+------+---------+--------+

我可以为每个现有行使用递增的seq#,但是,应用程序更改将采用现有的“几乎键”(基本上是事务#etail#),并递增此组合的序列号(因此,例如,我将有两行用于txn#1,细节#1,并且seq#1用于第一个,seq#2用于第二个,如果txn#513,细节#44有3个重复行,这些将具有seq#1,2,3恰当。这是理想的(从支持的角度来看),如果应用程序前后的数据更改同样如此。是否有一些简单的方法来创建此列,或者我是否需要手动循环行,每次txn#或detail#更改时重置使用的序列?

编辑添加:该应用程序部署在Postgresql 7.4& 8.1,解决方案需要适用于这两个版本。

2 个答案:

答案 0 :(得分:1)

如果你的专栏“几乎是独一无二的”,我即每个值没有多少重复,您可以使用以下语法:

ALTER TABLE mytable ADD seq INT;

UPDATE  mytable mo
SET     seq = 
        (
        SELECT  COUNT(*)
        FROM    mytable mi
        WHERE   mi.txn = mo.txn
                AND mi.detail = mo.detail
                AND mi.ctid <= mo.ctid
        )

ALTER TABLE mytable ALTER COLUMN seq SET NOT NULL;

ALTER TABLE mytable DROP CONSTRAINT t_mytable_pkey; -- the name of your current primary key

ALTER TABLE mytable ADD CONSTRAINT t_mytable_pkey PRIMARY KEY (txn, detail, seq);

如果没有太多重复,这将很快完成。

答案 1 :(得分:0)

您可以更改表格以创建新的主键列。然后,您可以在该表上创建一个插入和更新触发器,它将两个列组合在一起并将它们插入到右侧。

http://www.postgresql.org/docs/8.4/static/triggers.html