1

PostgreSQL 8.4.13 では、2 つのテーブルと 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コメント (列 ) を保持します。aboutidauthor

2 番目のテーブルでは、主キーのペアを宣言するのを忘れていました(その行は上でコメントされています)。

psqlプロンプトでその主キーを追加しようとしていますが、失敗します-おそらく何らかの理由で(上記の手順でどのように発生するかわかりませんか?)、同じauthorコメントidが何度か同じであるレコードがほとんどありません:

# 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.

私の質問は、 と の重複したペアを見つける方法idですauthor

私はもう試した:

# 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)

もちろん、それは私にペアを与えません...

更新: Catcall の提案 (ありがとう!) により、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プロンプトで多くのクエリを試しましたが失敗しました...

4

2 に答える 2

2

これにより、重複が識別されます。

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

これらの列は両方とも NULL を許可するため、NULL も確認する必要がある場合があります。

于 2013-02-04T14:21:23.030 に答える
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()

任意の式を指定できます。1すべての行がカウントされることを意味し1ますNULL。を使っても同じ効果count(*)count(1)実際、私は後者を好みますが、今回使用した理由はわかりません:)

于 2013-02-04T15:20:22.867 に答える