EXISTS
: existsの代わりに使用IN
する方が明確で (IMHO)、ほとんどの場合は高速です。(IN (...)
重複とNULLを削除/抑制する必要があるため、セットをソートします)
この特定のケースでは、集計サブクエリは、 group count() > 1
. クエリ オプティマイザーはこれを認識せず、完全なグループ カウントを (行の完全なセットに対して) 計算してから、それらを と比較する場合があり1
ます。
SELECT tt.id
FROM thetable tt
WHERE EXISTS (
SELECT * FROM thetable ex
WHERE ex.column1 = tt.column1 AND ex.id <> tt.id
);
WRT NULL の抑制:いずれか(または両方) が NULL であるWHERE ex.column1 = tt.column1
場合、句は常に falseになります。ex.column1
tt.column1
アップデート。OPは、さらにタプルがcolumn1 IS NULL
ある場合は、タプルも必要としているようです。簡単な解決策は、センチネル値 (ネイティブには に存在しない値columnn1
) を使用し、それをサロゲートとして使用することです (以下のフラグメントで-1
は、 がサロゲート値として使用されています)。
SELECT tt.id
FROM thetable tt
WHERE EXISTS (
SELECT * FROM thetable ex
WHERE COALESCE(ex.column1, -1) = COALESCE(tt.column1, -1)
AND ex.id <> tt.id
);
もう 1 つの (明らかな) 方法は、明示的に NULL をチェックすることですが、これには次のようなOR
句と一連の括弧が必要になります。
SELECT tt.id
FROM thetable tt
WHERE EXISTS (
SELECT * FROM thetable ex
WHERE (ex.column1 = tt.column1
OR (ex.column1 IS NULL AND tt.column1 IS NULL)
)
AND ex.id <> tt.id
);