Question

J'ai un gros problème avec une instruction SQL dans Oracle. Je veux choisir le TOP 10 enregistrements commandés par STORAGE_DB qui ne sont pas dans une liste d'une autre instruction select.

Celui-ci fonctionne très bien pour tous les enregistrements:

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') 

Mais quand je suis en ajoutant

AND ROWNUM <= 10
ORDER BY STORAGE_GB DESC

Je reçois une sorte de « aléatoires » Records. Je pense que la limite prend en place avant l'ordre.

Est-ce que quelqu'un a une bonne solution? L'autre problème: Cette requête est lente realy (10k + disques)

Était-ce utile?

La solution

comme ci-dessous, vous aurez besoin de mettre votre requête en cours dans la sous-requête:

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

rownum au résultat après qu'il a été retourné. ce que vous devez filtrer le résultat après qu'il a été retourné, donc un sous-requête est nécessaire. Vous pouvez également utiliser RANK () fonction pour obtenir Top-N résultats.
Pour essayer d'utiliser la performance NOT EXISTS en place de NOT IN. Voir cette plus.

Autres conseils

Si vous utilisez Oracle 12c, utilisez:

  

fetch SUIVANT N SEULEMENT RANGS

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

Plus d'infos: http://docs.oracle.com/javadb /10.5.3.0/ref/rrefsqljoffsetfetch.html

En ce qui concerne la mauvaise performance il y a un certain nombre de choses qu'il pourrait être, et il devrait vraiment être une question distincte. Cependant, il y a une chose évidente qui pourrait être un problème:

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

Si HISTORY_DATE est vraiment une colonne de date et si elle a un indice alors cette réécriture fonctionnera mieux:

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

En effet, une conversion du type désactive l'utilisation d'un index B-Tree.

essayer

SELECT * FROM users FETCH NEXT 10 ROWS ONLY;

Vous obtenez un jeu apparemment aléatoire car ROWNUM est appliqué avant la ORDER BY. Ainsi, votre requête prend les dix premières lignes et les tris them.0 Pour sélectionner les dix premiers salaires, vous devez utiliser une fonction analytique dans un sous-requête, puis filtre:

 select * from 
     (select empno,
             ename,
             sal,
             row_number() over(order by sal desc nulls last) rnm
    from emp) 
 where rnm<=10
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top