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票であるとします。 この番号とバインド:バインド、取得
IDNAME専門職投票
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
IDNAME専門職投票
0大佐ねこ

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

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

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

またね

Source: https://habr.com/ru/post/J269281/


All Articles