質問

いくつかのテーブルに参加し、かなりの数の列を返すクエリがあります。

別のテーブルのインデックス付き列は、これらの結合されたテーブルの1つのPKを参照しています。次に、新しいテーブルにそのIDを持つ少なくとも1つの行が存在する場合に、別の列をクエリに追加したいと思います。

したがって、古いテーブルの1つがある場合

ID
 1
 2
 3

そして新しいテーブル

REF_ID
1
1
1
3

それから私は取得したいです

ID   REF_EXISTS
 1            1
 2            0
 3            1

私はそれを行うためのいくつかの方法を考えることができますが、最もエレガント/効率的なものは何ですか?


編集古いテーブルに50.000のレコードが提供されたクエリのパフォーマンスをテストしました。他のすべてのレコードは新しいテーブルの2行と一致するため、レコードの半分にはref_exists = 1があります。

誰かが興味を持っている場合に備えて、回答へのコメントとして平均結果を追加しています。みんな、ありがとう!

役に立ちましたか?

解決

別のオプション:

select O.ID
    , case when N.ref_id is not null then 1 else 0 end as ref_exists
from old_table o
left outer join (select distinct ref_id from new_table) N
   on O.id = N.ref_id

他のヒント

私は...するだろう:

select distinct ID,
       case when exists (select 1 from REF_TABLE where ID_TABLE.ID = REF_TABLE.REF_ID)
    then 1 else 0 end
    from ID_TABLE

PKとFKにインデックスがある場合は、テーブルスキャンとインデックスルックアップで逃げます。

よろしくk

a join 1つのIDに対して複数の行を返すことができます。 id=1 例データで。グループを使用して、IDごとに1行に制限できます。

SELECT 
    t1.id
,   COUNT(DISTINCT t2.ref_id) as REF_EXISTS
FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id
GROUP BY t1.id

group by IDごとに1行しかないことを確認します。と count(distinct t2.ref_id) 行が見つかった場合は1、それ以外の場合は0になります。

編集:aなしで書き直すことができます group by, 、しかし、私はそれが物事をより簡単にするだろうと疑っています:

SELECT 
    t1.id
,   CASE WHEN EXISTS (
        SELECT * FROM TABLE_2 t2 WHERE t2.ref_id = t1.id)
        THEN 1 ELSE 0 END as REF_EXISTS
,   ....
FROM TABLE_1 t1

使用する:

   SELECT DISTINCT t1.id,
          CASE WHEN t2.ref_id IS NULL THEN 0 ELSE 1 END AS REF_EXISTS
     FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id

追加した DISTINCT 一意の行のみが表示されるようにします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top