web-dev-qa-db-ja.com

別の列ではなく、ある列からすべての値を選択する効率的な方法

colAからcolBにないすべての値をmytableから返す必要があります。使ってます:

SELECT DISTINCT(colA) FROM mytable WHERE colA NOT IN (SELECT colB FROM mytable)

動作していますが、クエリの完了に非常に長い時間がかかります。

これを行うためのより効率的な方法はありますか?

11
Flash

標準SQLでは、DISTINCT colA括弧なしがあります。 DISTINCTは関数ではありません。

SELECT DISTINCT colA
FROM   mytable
WHERE  colA NOT IN (SELECT DISTINCT colB FROM mytable);

副選択にもDISTINCTを追加しました。重複が多い場合は、クエリが高速化される可能性があります。

DBMSによっては、CTEの方が高速な場合があります。さらに、valBの値を除外する代替手段としてLEFT JOINを示し、GROUP BYを使用して個別の値を取得する代替方法を示します。

WITH x AS (SELECT colB FROM mytable GROUP BY colB)
SELECT m.colA
FROM   mytable m
LEFT   JOIN x ON x.colB = m.colA
WHERE  x.colB IS NULL
GROUP  BY m.colA;

または、さらに単純化して、単純なサブクエリ(おそらく最速)を使用します。

SELECT DISTINCT m.colA
FROM   mytable m
LEFT   JOIN mytable x ON x.colB = m.colA
WHERE  x.colB IS NULL;

別の(または同じ)テーブルに存在するキーを持つ行を除外するには、基本的に4つの手法があります。

速度の決定要因はインデックスになります。このクエリを高速にするには、colAcolBにインデックスを付ける必要があります。

18

existsを使用できます:

select distinct
    colA
from
    mytable m1
where
    not exists (select 1 from mytable m2 where m2.colB = m1.colA)

existsは、値をすばやく一致させるために半結合を実行します。 not inは結果セット全体を完成させ、次にorを実行します。 existsは通常、テーブルの値の方が高速です。

6
Eric

EXCEPT 演算子を使用して、2つのSELECTクエリを効果的に比較できます。 EXCEPT DISTINCTは一意の値のみを返します。 Oracleの MINUS 演算子はEXCEPT DISTINCTと同等です。

0
Paul