Oracle、典型的なSQLタスク。 保証された選択





選挙は進行中です。つまり、本日は知事を選出します。 より正確には、次のラウンドの候補者への障壁を任命する。 ただし、最初に条件を決定する必要があります。



SQLで保証される選択肢は何ですか? テーブルのクエリ条件で、フィールドと変数の比較が実行されるとします。 この変数の値に応じて、クエリはテーブルから行を返す場合と、まったく返さない場合があります。 そのような変数の値が落ちて、テーブルから行が返されない場合、この場合、事前に決定された左の結果を具体的に生成する必要があります。 つまり、いずれにしても、一般的なリクエストは何かを返すことを保証する必要があります。 用語自体はここから取られます 。 ただし、タスクは、値を持つ1つの単純なセルの代わりに、行全体を確実に返す必要があるという事実(またはその逆、簡略化)によって複雑になっています。



中央選挙管理委員会のデータを提供します。 投票の最初のラウンドはそのような結果で終了しました

ID 候補者名 職業 投票数
1 壊れないアモラルチストルコビッチ 検察官 9867
2 実効予算オスヴォイロヴィチ ビジネスマン 8650
3 真実 新聞編集者 745
4 ノーブル・ルシファー・フェオクティストナ 女神 234
5 フレンスゴリー・クタコイ・ニクトネズナエヴィッチ 田舎の学校の先生 3


create table election as with t (id, name, profession, votes) as ( select 1, '  ', '', 9867 from dual union all select 2, '  ', '', 8650 from dual union all select 3, '  ', ' ', 745 from dual union all select 4, '   ', '', 234 from dual union all select 5, '  ', '  ', 3 from dual ) select * from t; alter table election add primary key (id);
      
      





次のラウンドの候補を決定する最初の要求は非常に簡単です。

 select * from election where votes > :bound
      
      





通過障壁が8,000票であるとします。 この番号とバインド:バインド、取得

ID NAME 専門職 投票
1 壊れないアモラルチストルコビッチ 検察官 9867
2 実効予算オスヴォイロヴィチ ビジネスマン 8650


しかし、通過障壁が10,000、つまり、最大投票数を超える場合はどうでしょうか。 そして、次のラウンドの上記候補のいずれも合格しないことは明らかです。 この場合、独裁政権が確立され、猫大佐が自動的に地域の知事になります。 割り当て方法のいくつかを次に示します。



方法1.集約された自己を持つUNION ALLテーブル



 with t as ( select * from election where votes > :bound ) select id, name, profession, votes from t union all select 0, '', '', null from t having count(*) = 0 order by votes desc
      
      







方法2 DUALを含むUNION ALLテーブル

 with t as ( select * from election where votes > :bound ) select id, name, profession, votes from t union all select 0, '', '', null from dual where not exists (select null from t) order by votes desc
      
      







方法3. DUALを使用したLEFT JOINテーブル

 select nvl(e.id, 0) id, nvl2(e.id, e.name, '') name, nvl2(e.id, e.profession, '') profession, e.votes from dual d left join election e on e.votes > :bound order by e.votes desc
      
      





テーブルに一意のNOT NULLフィールドがない場合

 select nvl2(e.rowid, e.id, 0) id, nvl2(e.rowid, e.name, '') name, nvl2(e.rowid, e.profession, '') profession, e.votes from dual d left join election e on e.votes > :bound order by e.votes desc
      
      







方法4。猫とモデカ。

 select id, name, profession, votes from election where votes > :bound model dimension by (rownum rn) measures (id, name, profession, votes) rules ( name[1] = nvl2(id[1], name[1], ''), profession[1] = nvl2(id[1], profession[1], ''), id[1] = nvl(id[1], 0) ) order by votes desc
      
      









以下は、バリアが大きすぎるバインドでの保証された結果です10,000

ID NAME 専門職 投票
0 大佐 ねこ


8000の初期バーを設定すると、これらのクエリも正しく機能することは明らかです。



今のところすべてです。 キャラクター名と実在の人物とのすべての一致はランダムと見なされます。



他のいくつかの典型的なSQLタスクのソリューションは、 ここここにあります



またね



All Articles