2013-02-04 55 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個重複對中較老的(通過「郵票」欄)? –