2013-02-21 3 views
0
SELECT orderid 
FROM (SELECT orderid, rownum r 
     FROM (SELECT orderid 
       FROM myorders 
       WHERE ordertype = 'E' 
        AND orderstatus = 'A') a 
     WHERE rownum < 86) 
WHERE r > 84 

Quelle est la meilleure façon de réécrire l'instruction SQL ci-dessus de façon plus claire ...déclaration ORACLE SQL récrire

J'ai essayé ce qui suit, mais je ne reçois aucun résultat.

select orderid 
    from myorders 
where rownum between 84 and 86 
+5

il est inutile de prendre les lignes 84 à 86 si vous n'appliquez aucune sorte sur la table .... qu'est-ce que vous essayez d'atteindre ici? – haki

+0

qu'en est-il d'ordertype et d'orderstatus dans votre deuxième solution? –

+0

Je ne vois même pas comment votre première requête va compiler parce que vous sélectionnez rownum d'une sous-requête qui ne le contient pas. –

Répondre

2

est Indentation la première suggestion. Mais vous pouvez éliminer un ensemble de sous-requêtes:

select orderid 
from (SELECT orderid, rownum r 
     FROM myorders 
     WHERE ordertype = 'E' AND orderstatus = 'A' 
     ) a 
where r = 85 
3

En supposant que vous essayez de générer des pages de données et en supposant que votre désir est que les résultats sont stables et cohérentes si les données du tableau ne change pas (chaque ligne de la requête interne est renvoyée sur exactement une page des résultats que vous modifiez les limites supérieure et inférieure), l'approche la plus efficace serait essentiellement ce que vous avez publié initialement. Mais vous devez ajouter un ORDER BY à la requête interne. Dans le cas contraire, il serait tout à fait correct pour Oracle pour retourner une ligne de données sur chaque page ou de ne jamais renvoyer une ligne sur une page

SELECT orderid 
FROM (SELECT orderid, rownum r 
     FROM (SELECT orderid 
       FROM myorders 
       WHERE ordertype = 'E' 
        AND orderstatus = 'A' 
       ORDER BY <<something>>) a 
     WHERE rownum < 86) 
WHERE r > 84 

Si vous êtes vraiment plus préoccupés par la lisibilité de la performance, vous pourriez réduire un niveau d'imbrication en faisant quelque chose comme

SELECT orderid 
    FROM (SELECT orderid, 
       rank() over (order by <<something>>) rnk 
      FROM myorders 
     WHERE ordertype = 'E' 
      AND orderstatus = 'A') 
WHERE rnk > 84 
    AND rnk < 86 

Dans 12c Oracle, Oracle devrait soutenir la norme ANSI FETCH et OFFSET mots-clés pour simplifier la syntaxe un peu plus loin.

0

Si vous avez affaire à une seule table.

SELECT orderid 
FROM myorders 
WHERE ordertype = 'E' 
AND orderstatus = 'A' 
AND rownum between 84 and 86 
+0

Cela ne retournera jamais aucune valeur en raison de la façon dont la pseudo-colonne 'rownum' est générée. Ceci est expliqué [dans une réponse à une vieille question] (http://stackoverflow.com/a/855446/266304). –

+0

@JParadiso - Je suis d'accord avec Alex Poole - cela ne retournera jamais rien à cause de la nature de ROWNUM. Vous devriez tester vos exemples. Voici le test: SELECT empno FROM scott.emp OERE rownum entre 5 et 10 – Art

0

En outre, un exemple général de sélection entre lignes. Dans mon opinion personnelle, il est préférable d'utiliser ROW_NUMBER() et non ROWNUM. Ils sont compl. différent ...:

-- Between rows -- 
SELECT * FROM 
    (SELECT deptno, ename, sal 
      , ROW_NUMBER() OVER (ORDER BY ename) row_seq 
    FROM scott.emp) 
WHERE row_seq BETWEEN 5 and 10 
/