2013-02-04 17 views
1

在PostgreSQL 8.4.13我有2个表和程序,以填补第二个表:添加主键:表中包含重复值

create table pref_users (
      id varchar(32) primary key, 
      first_name varchar(64), 
      last_name varchar(64), 
      female boolean, 
      avatar varchar(128), 
      city varchar(64), 
      login timestamp default current_timestamp, 
      logout timestamp, 
      last_ip inet, 
      vip timestamp, 
      mail varchar(256) 
    ); 

    create table pref_rep (
      rep_id serial, 
      id varchar(32) references pref_users(id) check (id <> author) on delete cascade, 
      author varchar(32) references pref_users(id) on delete cascade, 
      author_ip inet, 
      good boolean, 
      fair boolean, 
      nice boolean, 
      about varchar(256), 
      stamp timestamp default current_timestamp 
      /* primary key(id, author) */ 
    ); 

    create or replace function pref_update_rep(_id varchar, 
      _author varchar, _author_ip inet, 
      _good boolean, _fair boolean, _nice boolean, 
      _about varchar) returns void as $BODY$ 
      begin 

      delete from pref_rep 
      where id = _id and 
      age(stamp) < interval '1 hour' and 
      (author_ip & '255.255.255.0'::inet) = 
      (_author_ip & '255.255.255.0'::inet); 

      update pref_rep set 
       author = _author, 
       author_ip = _author_ip, 
       good  = _good, 
       fair  = _fair, 
       nice  = _nice, 
       about  = _about, 
       stamp  = current_timestamp 
      where id = _id and author = _author; 

      if not found then 
        insert into pref_rep(id, author, author_ip, good, fair, nice, about) 
        values (_id, _author, _author_ip, _good, _fair, _nice, _about); 
      end if; 
      end; 
    $BODY$ language plpgsql; 

pref_users表保存有关用户的一般信息。

pref_rep持有约由另一个用户(列author)创建的用户(列id)评论(列about)。

对于第二张表,我忘记宣布primary key对(该行在上面注释)。

我想在psql提示符下添加主键,但是失败了 - 可能是因为某些原因(我不知道我的程序如何发生?)我有几个记录在同一位置author

# alter table pref_rep add primary key(id, author); 
NOTICE: ALTER TABLE/ADD PRIMARY KEY will create implicit index "pref_rep_pkey" for table "pref_rep" 
ERROR: could not create unique index "pref_rep_pkey" 
DETAIL: Table contains duplicated values. 

我的问题是如何找到那些重复的对idauthor:几次意见相同id

我已经试过:

# select id, count(id) from pref_rep group by id order by count desc limit 5; 
     id  | count 
----------------+------- 
OK408547485023 | 706 
OK261593357402 | 582 
DE11198  | 561 
DE13041  | 560 
OK347613386893 | 556 
(5 rows) 

但当然不会给我对...

UPDATE:嘘声的建议(!谢谢)给了我190,重复对:

  id   |   author   | count 
------------------------+------------------------+------- 
DE10598    | OK495480409724   |  2 
DE12188    | MR17925810634439466500 |  3 
DE13529    | OK471161192902   |  2 
DE13963    | OK434087948702   |  2 
DE14037    | DE7692     |  2 
...... 
VK45132921    | DE3544     |  2 
VK6152782    | OK261593357402   |  2 
VK72883921    | OK506067284178   |  2 
(190 rows) 

但实际上我真正的问题是如何删除(由stamp列)上了年纪的复制品?我已经在psql提示符下尝试了许多查询失败...

回答

1

这个查询是什么回事(也在SQL Fiddle)?

DELETE FROM pref_rep p USING (
    SELECT id, author, max(stamp) stamp 
    FROM pref_rep 
    GROUP BY id, author 
    HAVING count(1) > 1) AS f 
WHERE p.id=f.id AND p.author=f.author AND p.stamp<f.stamp; 

count()功能检查manual

您可以指定任何表达式。 1意味着所有行将被计数,'cos 1永远不会是NULL。如果您使用count(*),则效果相同。其实我更喜欢后者,不知道为什么我这次用了count(1) :)

+0

真棒,我不知道关于SQL小提琴:-) 我唯一不unserstand是:'计数(1)'' –

2

这应该标识重复项。

select id, author 
from pref_rep 
group by id, author 
having count(id) > 1 

您可能还必须查看NULL,因为这两列都允许NULL。

+0

谢谢!你有没有提示,如何删除190个重复对中较老的(通过“邮票”栏)? –