1

col1の特定の値のカウントをフェッチすることに関連するクエリがあります。しかし、プログラムロジックでIF条件を実行しているため、カウントを3までに制限することに関心があります。

val1によるタブグループからval1、count(1)cntを選択します。

    IF cnt=0
       --do something
    ELSIF cnt=1
      --do something
    ELSIF cnt=2
      --do something
    ELSIF cnt>2
      --do something
    ELSE
      --do something
    END IF;

このような大きなテーブル「TAB」ではオーバーヘッドが増えるため、2を超えて表示される値をカウントし続けたくありません。

3までカウントしてから、オラクルにval1のカウントを停止するように指示します。

たとえば、val1にItem001の値があり、val1に対応して、別の列val2に27個のコンポーネントがあります。しかし、val1でgroup byを実行すると、クエリはval1の発生を3までカウントする必要があります。カウントが3に達すると、テーブルのスキャンを停止する必要があります。カウントを取得するには、val1の他の値にジャンプする必要があります。

4

6 に答える 6

3

これを行う価値のある状況は限られていると思いますが、ID列を持つテーブルT1と、ID値を持つ別のテーブルT2が何度かあるとしましょう。最大3回までカウントしたい。

あなたが試みるかもしれないことは次のとおりです:

 select id,
        (select count(*) from t2 where t2.id = t1.id and rownum <= 3) c_star
 from   t1

http://sqlfiddle.com/#!4/1ab50/1/0

ただし、より通常のカウント方法に対して確実にベンチマークする必要があります。

編集:これがフルカウントよりも速いかもしれない状況について考えてみてください。

少数(15?)のデバイスがあり、それぞれが1秒あたり10個のメッセージを生成し、それらが日ごとにパーティション化され、インデックス付けされていないテーブルに挿入されているとします。それぞれが少なくとも毎日20通のメッセージをログに記録していることを確認したいとします。

パーティションのフルカウントは約1300万行ですが、デバイスあたりのカウントは20行に制限されているため、実際には15回のフルパーティションスキャンを実行します。これらはすべて、数行がスキャンされた後に(rownum制限を介して)終了します。 。

もちろん、故障したデバイスがある場合は、フルスキャンで終了します。

とにかく、それは私の頭から離れています。それが素晴らしいアイデアだと言っているわけではありませんが、それは可能です。

于 2012-12-18T10:42:21.880 に答える
1

Oracleがデータを読み取る方法を理解する必要があります。

エンジンは、ディスクからデータのブロックを要求します。次のブロックに何があるかはわかりません。たとえば、「Item001」がさらにあるか、新しいアイテムがあるかはわかりません。ブロックを読み取る必要があります-その中のすべての行。次に、Item001またはItem999をもう1つカウントすることは、ディスクからブロックを取得するために必要な時間と比較して何もありません。

これは、行がテーブルで順序付けられていないためです。エンジンは、val1にパーティション化されたテーブルがある場合を除いて、「item001sとItem002sなどがある」ことを認識しませんが、それはほとんど役に立たないと確信しています。

于 2012-12-18T09:10:35.790 に答える
0

正確にはわからないのですが、たった3回のカウントでポイントです...必要なものの発生をカウントするだけで、そのまま実行できますが、次のリンク情報が役立つかどうかを確認してください(使用しているOracleのバージョンがわからない):

http://www.orafaq.com/faq/how_does_one_select_the_top_n_rows_from_a_table

于 2012-12-18T08:20:51.213 に答える
0

rownumを使用して、行を最大3つに制限できます。これを使用すると、選択は3行目以降で停止するため、100000行はカウントされません。

于 2012-12-18T08:22:39.623 に答える
0

カウントを3に制限するには、次のようにします。

select val1, if(cnt > 2, 3, cnt) cnt
from (select val1, count(1) cnt
from tab
group by val1) x
于 2012-12-18T08:24:06.550 に答える
0

私は狂っていないと思います:)それを味わってください。

select mgr, (next_empno + next2_empno + 1) cnt 
from (
  SELECT empno, mgr,
    FIRST_VALUE(empno) OVER (PARTITION BY mgr ORDER BY empno) first_empno,
    LEAD(SIGN(empno), 1, 0) OVER (PARTITION BY mgr ORDER BY empno) next_empno,
    LEAD(SIGN(empno), 2, 0) OVER (PARTITION BY mgr ORDER BY empno) next2_empno
  FROM emp
)
where first_empno = empno

標準スキームを使用していますが、ここに SQLFiddleがあります(非常に優れたサービス:))

于 2012-12-18T11:43:47.217 に答える