web-dev-qa-db-ja.com

CTEのUPDATE後にDELETEが機能しないのはなぜですか?

CREATE table test (
    id integer,
    x integer
);

INSERT INTO test VALUES (1, 1);

SELECTは機能します:

WITH res AS (
    UPDATE test SET x = 10 WHERE id = 1
    RETURNING id
)
SELECT id FROM test WHERE id IN (SELECT id FROM res);

id 
---
 1
(1 row)

しかし、DELETEは機能しません:

WITH res AS (
    UPDATE test SET x = 10 WHERE id = 1
    RETURNING id
)
DELETE FROM test WHERE id IN (SELECT id FROM res);

DELETE 0
2
Igor Che

共通テーブル式(CTE) 同じステートメントの==は、データベースの同じスナップショットに基づくallです。つまりすべてのサブステートメントは、基になるテーブルの同じ状態を参照します。

DELETEは、UPDATEがすでに変更している同じ行を変更しようとします。 マニュアルはあなたのケースに対応しています正確に

1つのステートメントで同じ行を2回更新しようとすることはサポートされていません。変更は1つだけ行われますが、どれを確実に予測するかは簡単ではありません(場合によっては不可能です)。 これは、同じステートメントですでに更新された行の削除にも適用されます。更新のみが実行されます。したがって、通常、単一の行を変更しようとしないでください。 1つのステートメントで2回行します。特に、メインステートメントまたは兄弟サブステートメントによって変更された同じ行に影響を与える可能性のあるWITHサブステートメントの記述は避けてください。そのような声明の効果は予測できません。

大胆な強調鉱山。

2