0

エンティティ間の関係を記述する Postgres テーブルがあります。このテーブルは、変更できないプロセスによって入力されます。これはそのテーブルの例です:

+-----+-----+
| e1  | e2  |
|-----+-----|
|  A  |  B  |
|  C  |  D  |
|  D  |  C  |
| ... | ... |
+-----+-----+

テーブルから不要なリレーションシップをすべて削除する SQL クエリを作成したいと考えてい[D, C]ます[C, D]

自己結合を使用して削除するクエリがありますが、これにより関係に関係するすべてが削除されます。

DELETE FROM foo USING foo b WHERE foo.e2 = b.e1 AND foo.e1 = b.e2;

結果:

+-----+-----+
| e1  | e2  |
|-----+-----|
|  A  |  B  |
| ... | ... |
+-----+-----+

ただし、関係の 1 つを残すクエリが必要です。どちらの関係が残っているか、[C, D]または[D, C]両方が残っているかは問題ではありません。

ここには簡単な解決策があるように感じますが、それは私を逃れています。

4

2 に答える 2

2

一般的な解決策は、常に一意の疑似列を使用することですctid

DELETE FROM foo USING foo b WHERE foo.e2 = b.e1 AND foo.e1 = b.e2
    AND foo.ctid > b.ctid;

ちなみに、物理的な場所がテーブルの最初のデータページに最も近いタプルを保持します。

于 2013-09-12T17:21:35.010 に答える
1

正確な重複行が制約されていると仮定すると、特定の関係には常に最大で 2 つの行があります: (C,D) と (D,C) の例では。同じ制約は、2 つの列が異なる値を持つことも意味します。ペア (C,C) は有効かもしれませんが、複製することはできません。

関連するデータ型の定義が適切であると仮定すると、>削除する行が最初の列>が 2 番目の列であるという条件を追加し、他の行はそのままにしておくことができます。

サンプル クエリでは、これはAND foo.e1 > foo.e2.

于 2013-09-12T17:34:25.880 に答える