6

複数のテーブルを結合し、かなりの数の列を返すクエリがあります。

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

だから私が古いテーブルの1つを持っているなら

ID
 1
 2
 3

そして新しいテーブル

REF_ID
1
1
1
3

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

ID   REF_EXISTS
 1            1
 2            0
 3            1

それを行う方法はいくつか考えられますが、最もエレガントで効率的な方法は何ですか?


EDIT 古いテーブルの50.000レコードで提供されたクエリのパフォーマンスをテストしました.1つおきのレコードは新しいテーブルの2行と一致しているため、レコードの半分はREF_EXISTS = 1です。

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

4

4 に答える 4

8

別のオプション:

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
于 2009-12-16T20:24:56.147 に答える
4

私は...するだろう:

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

于 2009-12-17T12:50:10.400 に答える
2

使用する:

   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一意の行のみが表示されるようにするために追加されました。

于 2009-12-16T19:38:22.310 に答える
1

サンプル データの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 になります。

編集: なしで書き直すことができますが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
于 2009-12-16T19:42:10.970 に答える