質問

私はOracleでSQL文を使用した大きな問題を抱えています。私は他のselect文からリストにない10レコードがSTORAGE_DBが注文したTOPを選択します。

この1は、すべてのレコードの罰金に動作します:

SELECT DISTINCT 
  APP_ID, 
  NAME, 
  STORAGE_GB, 
  HISTORY_CREATED, 
  TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE  
  FROM HISTORY WHERE 
      STORAGE_GB IS NOT NULL AND 
        APP_ID NOT IN (SELECT APP_ID
                       FROM HISTORY
                        WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') = '06.02.2009') 

しかし、私は追加していたときに、

AND ROWNUM <= 10
ORDER BY STORAGE_GB DESC
私は「ランダム」のレコードのいくつかの種類を取得しています。リミット注文前に所定の位置になりますので、私は考えてます。

ないの誰かが良い解決策を持っていますか?その他の問題:このクエリが本当に遅いです(10K +記録)

役に立ちましたか?

解決

あなたは以下のようにサブクエリであなたの現在のクエリを配置する必要があります

SELECT * FROM (
  SELECT DISTINCT 
  APP_ID, 
  NAME, 
  STORAGE_GB, 
  HISTORY_CREATED, 
  TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE  
  FROM HISTORY WHERE 
    STORAGE_GB IS NOT NULL AND 
      APP_ID NOT IN (SELECT APP_ID FROM HISTORY WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') ='06.02.2009')
  ORDER BY STORAGE_GB DESC )
WHERE ROWNUM <= 10

Oracleは、それが返された後の結果に ROWNUMのに適用されます。
あなたはそれが戻ってきた後にサブクエリが必要とされるように、結果をフィルタリングする必要があります。また、トップNを取得するために RANK()の機能を使用することができます結果。

パフォーマンスのためにNOT EXISTSの代わりにNOT INを使用してみてください。 以上のため、このに。

を参照してください。

他のヒント

は、Oracle 12cは、使用している場合は使用します:

  

FETCH NEXTの のN のROWS ONLY

SELECT DISTINCT 
  APP_ID, 
  NAME, 
  STORAGE_GB, 
  HISTORY_CREATED, 
  TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE  
  FROM HISTORY WHERE 
    STORAGE_GB IS NOT NULL AND 
      APP_ID NOT IN (SELECT APP_ID FROM HISTORY WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') ='06.02.2009')
  ORDER BY STORAGE_GB DESC
FETCH NEXT 10 ROWS ONLY

詳細情報: http://docs.oracle.com/javadb /10.5.3.0/ref/rrefsqljoffsetfetch.htmlする

パフォーマンスの低下に関してはそれができるものの任意の数が存在し、それは本当に別の問題であるべきです。しかし、問題になる可能性が1つの明らかなものがあります:

WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') = '06.02.2009') 

HISTORY_DATEが本当に日付列であり、それはインデックスを持っている場合、この書き換えが行われる場合は、より良います:

WHERE HISTORY_DATE = TO_DATE ('06.02.2009', 'DD.MM.YYYY')  

データ型変換は、B-Treeインデックスの使用を無効にためである。

のtry

SELECT * FROM users FETCH NEXT 10 ROWS ONLY;
ROWNUMは、ORDER BYの前に適用されるため、

あなたは明らかにランダムなセットを取得します。あなたのクエリは、フィルタ、その後、最初の10行を取り、あなたがサブクエリで分析関数を使用する必要があり、トップ10の給与を選択するにはthem.0をソートするようにます:

 select * from 
     (select empno,
             ename,
             sal,
             row_number() over(order by sal desc nulls last) rnm
    from emp) 
 where rnm<=10
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top