1

2 つの条件が該当するかどうかを確認する必要がある ID を持つテーブルがあります。各条件は、where 句のセットです。

たとえば、チェックする必要があるのは Table1 です。

1 番目の条件:

select t1.id 
from table1 t1, table2 t2, table3 t3 
where 
     condition1,
     condition2,
     condition3

2 番目の条件:

 select t1.id 
 from table1 t1, table2 t2, table4 t4
 where
     condition1,
     condition4,
     condition5

ここで、1 番目の条件または 2 番目の条件が同じ ID またはその両方に適用されるかどうかを確認する必要があります。ユニオンを使用し、各条件の select ステートメントに静的な値を追加するように言われました (例: 1 番目の条件select t1.id, 1と 2 番目の条件の場合select t1.id, 2)。

テーブルは非常に大きく、何百万ものレコードが含まれているため、パフォーマンスを向上させるために 1 つの SQL でこれを行う必要があります。また、C コードから結果にアクセスしていますが、返される結果の数がわからないため、各クエリを単独で実行し、結果をそれぞれの配列に保存し、各配列でループを実行して、両方または 1 つの条件が適用される ID を確認します。これは、ID ごとに異なる処理が適用される条件に基づいて実行されるためです。 .

編集 例:

 t1 ids: 1, 2, 3, 4

 for id = 1, only condition 1 apply
 for id = 2, only condition 2 apply
 for id = 3, both conditions apply
 for id = 4, no condition apply

結果には、1 つまたは 2 つのランダムな静的フラグを含む次のものが必要です。

  id      1       2
  -----------------
  1      1
  2              2
  3      1       2

私はそれが厄介に聞こえることを知っています、それが可能かどうかさえ確信が持てません

どうもありがとう :)

4

5 に答える 5

0

これは、妥当な時間内に必要なことを実行する必要がある単一のクエリです。

with tmp1 as (
    select t1.id
    from table1 t1, table2 t2, table3 t3 
    where 
         condition1,
         condition2,
         condition3
), tmp2 as (
    select t1.id
    from table1 t1, table2 t2, table4 t4
    where
        condition1,
        condition4,
        condition5
)
select distinct t1.id, t2.cond as cond1, t3.cond as cond2
from table1 t1, tmp1 t2, tmp2 t3
where t1.id = t2.id(+)
and t1.id = t3.id(+)
and not (t2.cond is null and t3.cond is null)
;

注:これは、ammoQの(よりエレガントな)完全な外部結合の回答と非常によく似ています。

于 2012-11-29T11:54:09.077 に答える
0

これは、たとえば次のような明示的な結合の場合だと思います。

select
  t1.id,
  case when t2a.id is not null and t3.id is not null then 1 end condition_1st,
  case when t2b.id is not null and t4.id is not null then 1 end condition_2nd
from table1 t1
left join table2 t2a on condition2
left join table3 t3  on condition3
left join table2 t2b on condition4
left join table4 t4  on condition5
where contition1
于 2012-11-29T11:37:54.667 に答える
0

クエリに関係なく、行が1つ以上の条件を満たしているかどうかにフラグを立てる最良の方法は、caseステートメントを使用することです...

 select id,
        case when condition1 then 1 else 0 end met_condition1,
        case when condition2 then 1 else 0 end met_condition2
 from   my_table
 where  condition1 or
        condition2

編集:

オプティマイザーには「条件 1 または条件 2」をユニオン (すべて) クエリに変換するオプションがあるため、通常、この定式化は (query1 union query 2) メソッドよりも最初に選択しますが、逆に変換できることを思い出せません。方向。

また、オプティマイザーは、条件が相互に排他的であることを常に認識できるとは限りません。これにより、UNION の代わりに UNION ALL が許可され、不要な UNION 駆動の DISTINCT 操作に悩まされる可能性があります。

もちろん、オプティマイザーが常に正しいとは限りませんが、動的サンプリングは、特に行が両方の条件に一致する場合に、決定に大きなプラスの影響を与える可能性があります。

別の編集:

過去に、条件 1 と条件 2 を個別のインデックスで満たすことができそれらの結果セットにある程度の重複がある場合、フォームのクエリで良い経験をしたことがありました...

 select ...
 from   ...
 where  rowid in (
          select rowid
          from   ...
          where  condition_1
          union
          select rowid
          from   ...
          where  condition_2)

条件 1 と 2 に関係なく適用される他の条件があり、データ セットを妥当な量だけ削減することも役立つ場合があります。

 with baseline as (
    select ...
    from   ...
    where  common_condition_set)
 select ...
 from   baseline
 where  condition_1 or condition_2

また

 with baseline as (
    select ...
    from   ...
    where  common_condition_set)
 select ...
 from   baseline
 where  condition_1
 union
 select ...
 from   baseline
 where  condition_2
于 2012-11-29T11:39:41.523 に答える
0

UPDT

    select t1.id as first, ttt.id as second
    from table1 t1, table2 t2, table3 t3,
(select t1.id 
     from table1 t1, table2 t2, table4 t4
     where
         condition1,
         condition4,
         condition5) ttt
    where 
         condition1,
         condition2,
         condition3
于 2012-11-29T11:26:34.563 に答える
0

サブクエリは 1 つの解決策ですが、よりエレガントな (あまり知られていませんが) 方法があります:intersect節です。と同様に機能unionしますが、結合ではなく交差を行います。

select t1.id 
from table1 t1, table2 t2, table3 t3 
where 
     condition1,
     condition2,
     condition3
intersect
 select t1.id 
 from table1 t1, table2 t2, table4 t4
 where
     condition1,
     condition4,
     condition5

同様にminus、最初のクエリにのみ表示されるレコードを検索するために使用できます。

select t1.id 
from table1 t1, table2 t2, table3 t3 
where 
     condition1,
     condition2,
     condition3
minus
 select t1.id 
 from table1 t1, table2 t2, table4 t4
 where
     condition1,
     condition4,
     condition5

(クエリを入れ替えて、2 番目のクエリにのみ表示されるものを見つけます)

1 つのクエリですべてを取得するには、完全外部結合を使用する必要があります。

with q1 as (
select t1.id 
from table1 t1, table2 t2, table3 t3 
where 
     condition1,
     condition2,
     condition3),
q2 as (
 select t1.id 
 from table1 t1, table2 t2, table4 t4
 where
     condition1,
     condition4,
     condition5
)
select nvl(q1.id, q2.id) as id,
  case when q1.id is not null then 1 else null end "1",
  case when q2.id is not null then 2 else null end "2"
  from q1 full outer join q2 on q1.id = q2.id
于 2012-11-29T11:28:24.903 に答える