J'ai un gros problème avec une instruction SQL dans Oracle. Je souhaite sélectionner les 10 meilleurs enregistrements classés par STORAGE_DB qui ne figurent pas dans une liste d'une autre instruction SELECT.
Celui-ci fonctionne 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 j'ajoute
AND ROWNUM <= 10
ORDER BY STORAGE_GB DESC
Je reçois une sorte de disques "aléatoires". Je pense parce que la limite a lieu avant la commande.
Quelqu'un a-t-il une bonne solution? L'autre problème: cette requête est vraiment lente (10k + enregistrements)
Réponses:
Vous devrez mettre votre requête actuelle dans la sous-requête comme ci-dessous:
Oracle applique le rownum au résultat une fois qu'il a été renvoyé.
Vous devez filtrer le résultat après son renvoi, une sous-requête est donc requise. Vous pouvez également utiliser la fonction RANK () pour obtenir les résultats Top-N.
Pour les performances, essayez d'utiliser
NOT EXISTS
à la place deNOT IN
. Voir ceci pour plus.la source
FETCH NEXT N ROWS ONLY
réponse ci-dessous.Si vous utilisez Oracle 12c, utilisez:
Plus d'infos: http://docs.oracle.com/javadb/10.5.3.0/ref/rrefsqljoffsetfetch.html
la source
En ce qui concerne la mauvaise performance, il y a un certain nombre de choses que cela pourrait être, et cela devrait vraiment être une question distincte. Cependant, il y a une chose évidente qui pourrait être un problème:
Si HISTORY_DATE est vraiment une colonne de date et si elle a un index, cette réécriture fonctionnera mieux:
En effet, une conversion de type de données désactive l'utilisation d'un index B-Tree.
la source
essayer
la source
Vous obtenez un ensemble apparemment aléatoire car ROWNUM est appliqué avant ORDER BY. Votre requête prend donc les dix premières lignes et les trie.0 Pour sélectionner les dix meilleurs salaires, vous devez utiliser une fonction analytique dans une sous-requête, puis filtrer cela:
la source