IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Oracle Discussion :

[SQL] Limitation avec tri


Sujet :

Oracle

  1. #1
    Membre averti
    Inscrit en
    Janvier 2004
    Messages
    533
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 533
    Points : 313
    Points
    313
    Par défaut [SQL] Limitation avec tri
    Bonjour,

    je souhaite trier un jeu d'enregistrements, en le limitant. Cependant, avec la requête ci-dessous, mon jeu d'enregistrements est limité mais non trié. Les 20 enregistrements qui sortent ne correspondent pas aux 20 premiers de la sous-requête.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT *
    FROM(
        SELECT  produit,
    	    pdt_ecart AS ecart,
    	    ROWNUM AS n
        FROM table_produits
        ORDER BY abs(pdt_ecart) DESC
        )
    WHERE n BETWEEN 0 AND 20
    Comment faire ?
    Merci d'avance.
    @+

  2. #2
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075

  3. #3
    Membre averti
    Inscrit en
    Janvier 2004
    Messages
    533
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 533
    Points : 313
    Points
    313
    Par défaut
    Ma syntaxe semble correcte. Pourtant les jeux d'enregistrements diffèrent bien.

  4. #4
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Trie ta requete principale sur n

  5. #5
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    tu peux nous montrer le résultat STP ?

  6. #6
    Membre averti
    Inscrit en
    Janvier 2004
    Messages
    533
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 533
    Points : 313
    Points
    313
    Par défaut
    Citation Envoyé par McM
    Trie ta requete principale sur n
    J'ai mis n dans le order by, mais cela ne change rien...

    Citation Envoyé par Fred_D
    tu peux nous montrer le résultat STP ?
    Euh... non, désolée. Ce sont des données que je ne peux divulguer. Tout ce que je peux dire, c'est que je trouves 2 listes de données différentes...

  7. #7
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT *
    FROM(
        SELECT  produit,
    	    pdt_ecart AS ecart
        FROM table_produits
        ORDER BY abs(pdt_ecart) DESC
        )
    WHERE rownum BETWEEN 0 AND 20

  8. #8
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Cela dit 20 données inconnues de tout le monde..

    Question, quelles sont les valeurs de abs(pdt_ecart) ?
    Est-ce qu'elles sont différentes sur les 20 premières lignes ?

  9. #9
    Membre averti
    Inscrit en
    Janvier 2004
    Messages
    533
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 533
    Points : 313
    Points
    313
    Par défaut
    McM, pour répondre à ta dernière question, oui ces données étaient différentes.

    Par contre, la requête postée par plaineR correspond à mes attentes et fonctionne très bien.

    Merci beaucoup !!!

  10. #10
    Membre averti

    Inscrit en
    Septembre 2003
    Messages
    425
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 425
    Points : 398
    Points
    398
    Par défaut
    Je pense que les fonction analytique devrait t'aider (merci Fred_D )

    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT *
    FROM(
    SELECT  produit,
    pdt_ecart AS ecart,
    rank()over(order by abs(pdt_ecart)) as n
    FROM table_produits
        )
    WHERE n BETWEEN 0 AND 20
    j'ai fait un essai avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    with table_produits as (
    select 'A' produit, 8 pdt_ecart from dual union 
    select 'B' produit, 7 pdt_ecart from dual union
    select 'C' produit, 6 pdt_ecart from dual union
    select 'D' produit, 5 pdt_ecart from dual union
    select 'E' produit, 4 pdt_ecart from dual union
    select 'Z' produit, 14 pdt_ecart from dual union
    select 'G' produit, 18 pdt_ecart from dual union
    select 'H' produit, 1 pdt_ecart from dual ) 
    SELECT *
    FROM(
    SELECT  produit,
    pdt_ecart AS ecart,
    rank()over(order by abs(pdt_ecart)) as n
    FROM table_produits
        )
    WHERE n BETWEEN 0 AND 2
    mais sans ton jeux de données c'est pas tres évident

    oups pas vu que la solutions était trouvée bon tant pis

  11. #11
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    ce serait plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT *
    FROM(
        SELECT  produit,
    	    pdt_ecart AS ecart
        FROM table_produits
        ORDER BY abs(pdt_ecart) DESC
        )
    WHERE rownum BETWEEN 0 AND 20

  12. #12
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Citation Envoyé par Fred_D
    ce serait plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT *
    FROM(
        SELECT  produit,
    	    pdt_ecart AS ecart
        FROM table_produits
        ORDER BY abs(pdt_ecart) DESC
        )
    WHERE rownum BETWEEN 0 AND 20
    Copieur !!!! Ce serait pas un peu la solution que j'ai proposée ?

  13. #13
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    j'avais pas vu :paf:

    mais du coup, il y a une erreur dans la FAQ

  14. #14
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Normalement ça te permet de récupérer de la ligne 10 à la 20...
    Faut tester pourquoi ça marche pas...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT rownum n, a FROM MATABLE ORDER BY a
    le rownum est fait avant le tri.
    faut faire pour la sous requete
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT rownum n, a FROM ( SELECT a FROM MATABLE ORDER BY a)
    et pour les enregs de n1 à n2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT n, a
    FROM (
      SELECT rownum n, a 
      FROM ( SELECT a FROM MATABLE ORDER BY a)
        )
    WHERE n BETWEEN n1 AND n2
    ORDER BY n

  15. #15
    Membre averti
    Inscrit en
    Janvier 2004
    Messages
    533
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 533
    Points : 313
    Points
    313
    Par défaut
    J'ai l'impression que ça équivaut à ce qui est dit au dessus... En tout cas, merci pour ces précisions, ce n'était pas facile à faire !

  16. #16
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    Citation Envoyé par navis84
    J'ai l'impression que ça équivaut à ce qui est dit au dessus... En tout cas, merci pour ces précisions, ce n'était pas facile à faire !
    Non la solution de McM est la seule qui te garantisse que ça fonctionne toujours quel que soit ton encadrement... essaye la solution de plaineR en ramenant les lignes de 10 à 20 tu comprendras ce que je veux dire...

  17. #17
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    quoi que il y a un tout petit peu plus simple finalement à mon avis en restant très proche de ce que tu avais fait....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT *
    FROM(
        SELECT  produit,
    	    pdt_ecart AS ecart,
    	    ROWNUM AS n
        FROM table_produits
        ORDER BY abs(pdt_ecart) DESC
        )
    WHERE n BETWEEN 30 AND 40
    ORDER BY n
    C'est vrai qu'on aurait pu s'attendre à ce qu'un select sur un truc trié reste trié, mais ce n'est en rien une garantie d'oracle, si tu veux un tri tu fait "ORDER BY" est pi voilà... apparament tu es tombé sur un cas rare mais pas abérant...

    Quand je vous dit moi que le rownum est pleins de pieges....

  18. #18
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    Attention il ce n'est pas forcément le rank qu'il faille utiliser mais le row_number. Le rank classe au meme rang 2 lignes de valeurs égales alors que le row_number choisi un classement de manière arbitraire. meme quand 2 lignes sont égales le row_number est toujours différent. Ainsi le row_number te garanti un nombre fixe de lignes pas le rank.

    A mon avis solution la plus propre serait donc (si c'est de la pagination que tu veux faire)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT *
    FROM(
        SELECT  produit,
    	    pdt_ecart AS ecart,
    	    ROW_NUMBER() over (ORDER BY abs(pdt_ecart)) AS n
        FROM table_produits
        )
    WHERE n BETWEEN 30 AND 40
    ORDER BY n

  19. #19
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Citation Envoyé par remi4444
    Non la solution de McM est la seule qui te garantisse que ça fonctionne toujours quel que soit ton encadrement... essaye la solution de plaineR en ramenant les lignes de 10 à 20 tu comprendras ce que je veux dire...
    D'un autre côté je me suis contenté de répondre à sa question qui était comment ramener les 20 premiers enregistrements

    Citation Envoyé par remi4444
    A mon avis solution la plus propre serait donc (si c'est de la pagination que tu veux faire)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT *
    FROM(
        SELECT  produit,
    	    pdt_ecart AS ecart,
    	    ROW_NUMBER() over (ORDER BY abs(pdt_ecart)) AS n
        FROM table_produits
        )
    WHERE n BETWEEN 30 AND 40
    ORDER BY n
    Sans aucun doute la meilleure solution (pour les versions > 8i)

  20. #20
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Citation Envoyé par remi4444
    C'est vrai qu'on aurait pu s'attendre à ce qu'un select sur un truc trié reste trié, mais ce n'est en rien une garantie d'oracle, si tu veux un tri tu fait "ORDER BY" est pi voilà... apparament tu es tombé sur un cas rare mais pas abérant...

    Quand je vous dit moi que le rownum est pleins de pieges....
    Non ce n'est pas un cas rare, le order by se fait après le rownum :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    SQL> select * from dvp;
            A
    ---------
            5
            2
            4
            3
            1
     
    SQL> select a, rownum from dvp order by a;
            A    ROWNUM
    --------- ---------
            1         5
            2         2
            3         4
            4         3
            5         1

    Citation Envoyé par remi4444
    quoi que il y a un tout petit peu plus simple finalement à mon avis en restant très proche de ce que tu avais fait....
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT *
    FROM(
        SELECT  produit,
    	    pdt_ecart AS ecart,
    	    ROWNUM AS n
        FROM table_produits
        ORDER BY abs(pdt_ecart) DESC
        )
    WHERE n BETWEEN 30 AND 40
    ORDER BY n
    => cette solution n'est donc pas bonne.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Query SQL avec tri sur une date + groupement
    Par Raphael1980 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 24/02/2009, 16h12
  2. Requête SQL avec tri avancé
    Par Lexarino dans le forum Débuter
    Réponses: 5
    Dernier message: 17/01/2009, 12h54
  3. [SQL] Limiter taille tableau html construit avec données sql
    Par syl2042 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 26/09/2007, 16h23
  4. [SQL] Liste déroulante à partir d'une table avec tri
    Par ksper92 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 28/11/2006, 12h25
  5. [SQL] SELECT avec tri et limite
    Par Resyek dans le forum Langage SQL
    Réponses: 1
    Dernier message: 04/04/2006, 16h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo