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

Langage SQL Discussion :

Sélectionner les lignes qui ont la valeur maximale dans une certaine colonne


Sujet :

Langage SQL

  1. #1
    Membre habitué Avatar de Orhleil
    Homme Profil pro
    Intégrateur fonctionnel
    Inscrit en
    Mai 2011
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Intégrateur fonctionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 81
    Points : 152
    Points
    152
    Par défaut Sélectionner les lignes qui ont la valeur maximale dans une certaine colonne
    Bonjour à tous,

    J'ai une requête assez complexe (ci-après nommée ma_requete_qui_fait_plein_de_trucs qui rapatrie tout un tas de données et dont je souhaiterais ne récupérer que les lignes qui ont la valeur maximale d'une certaine colonne. C'est-à-dire, j'ai des données de ce genre là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT Valeur, Colonne1, Colonne2, ..., ColonneN
    FROM ma_requete_qui_fait_plein_de_trucs
    ... et je voudrais ne garder que les lignes qui ont dans la colonne Valeur la valeur maximale de toute la colonne.

    Une façon de faire ça serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT Valeur, Colonne1, Colonne2, ..., ColonneN
    FROM ma_requete_qui_fait_plein_de_trucs
    WHERE Valeur = (SELECT MAX(Valeur) FROM ma_requete_qui_fait_plein_de_trucs)
    Mais cette méthode implique d'exécuter deux fois ma_requete_qui_fait_plein_de_trucs, ce qui n'est ni très économe, ni très ergonomique dans le code.

    N'ayant que des droits très limités sur la base de données, je ne peux pas créer de vue ou ce genre de chose (ou plus exactement je peux en créer, mais on nous l'a interdit... (fichus décideurs )).
    J'ai du mal à croire que cette sélection de ligne ne soit pas possible par le biais d'une astuce SQL, mais je n'arrive pas à trouver comment faire.

    La colonne Valeur contient des entiers positifs. La base de données est gérée par Oracle (je ne saurais pas dire quelle version).

    Merci par avance de votre aide !

    EDIT : plus d'explications du problème dans mon message suivant

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    bonjour,


    tant que vous n'exprimez pas clairement votre besoin, ni votre_grosse_requete personne ne pourra repondre

  3. #3
    Membre habitué Avatar de Orhleil
    Homme Profil pro
    Intégrateur fonctionnel
    Inscrit en
    Mai 2011
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Intégrateur fonctionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 81
    Points : 152
    Points
    152
    Par défaut
    Je pensais que le besoin était suffisamment clair, navré s'il ne l'était pas. Et la requête je n'ai pas le droit de la diffuser (on sait jamais hein, des fois que vous soyez des hackeurs malveillants et tout ça... T_T).

    Je ne vois pas trop comment mieux exprimer le besoin...

    Mais bon je vais vous fabriquer un exemple plus concret si ça peut vous aider.
    Imaginons une table de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Table : FOURNISSEURS
       ID   |   VILLE   | NB_PRODUITS | DUREE_CONTRAT_ANS
        1   |  'PARIS'  |      12     |        1
        2   |  'PARIS'  |      36     |        5
        3   |  'PARIS'  |      24     |        2
        4   |  'LYON'   |      36     |        2
        5   |  'RENNES' |      12     |        3
        6   |  'RENNES' |      48     |        5
        7   |  'LYON'   |      36     |        6
        8   |  'LYON'   |      12     |        10
        9   |  'PARIS'  |      24     |        1
    Maintenant mettons que je souhaite récupérer les plus gros fournisseurs (tous ceux qui proposent le nombre de produits le plus élevé) parmi ceux situés à Lyon.
    Pour trouver les gens de Lyon j'ai une requête de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM FOURNISSEURS
    WHERE VILLE = 'LYON'
    Ce qui nous renvoie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       ID   |   VILLE   | NB_PRODUITS | DUREE_CONTRAT_ANS
        4   |  'LYON'   |      36     |        2
        7   |  'LYON'   |      36     |        6
        8   |  'LYON'   |      12     |        10
    Mais à partir de ça je ne vois pas trop comment récupérer les plus gros fournisseurs, c'est-à-dire ceux qui ont un NB_PRODUITS égal au MAX(NB_PRODUITS) de ce résultat de requête, ici 36.
    Mon objectif final est donc d'avoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       ID   |   VILLE   | NB_PRODUITS | DUREE_CONTRAT_ANS
        4   |  'LYON'   |      36     |        2
        7   |  'LYON'   |      36     |        6
    La seule vraie méthode que je vois c'est de faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT *
    FROM FOURNISSEURS
    WHERE VILLE = 'LYON'
          AND NB_PRODUITS = (SELECT MAX(NB_PRODUITS)
                             FROM FOURNISSEURS
                             WHERE VILLE = 'LYON')
    ... mais cette méthode implique d'exécuter 2 fois le SELECT qui restreint aux fournisseurs de Lyon, ce qui dans le cas de ma vraie requête n'est franchement pas judicieux.

    Voilà, est-ce que ça rend mon besoin plus clair ?
    Merci de votre attention et de votre aide

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Points : 1 199
    Points
    1 199
    Par défaut
    Bonjour,
    Un réponse à ta problématique pourrait être les fonctions de fenêtrage et notamment rank over partition.
    Ce qui donnerait quelque chose comme cela.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    WITH MES_FOURNISSEURS 
    AS
    (
    SELECT *, RANK ( ) OVER ( VILLE orderby NB_PRODUITS DESC) AS RANG
    FROM FOURNISSEURS
    WHERE VILLE = 'LYON'
    )
    SELECT * from MES_FOURNISSEURS 
    where RANG=1
    De mémoire au moins sous SQL server il n'est pas possible d'utiliser RANK dans un WHERE directement.

    Sinon une alternative pourrait être toujours avec une Common Table Expression (clause With)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    WITH  MES_FOURNISSEURS 
    AS
    (
    SELECT *
    FROM FOURNISSEURS
    WHERE VILLE = 'LYON'
    )
    SELECT A.*
    From MES_FOURNISSEURS A
    INNER JOIN
    ( SELECT MAX(NB_PRODUITS ) as NB_PRODUITS_MAX
    FROM MES_FOURNISSEURS
    )B
    on A.NB_PRODUITS=B.NB_PRODUITS
    J'espère que ta version d'ORACLE supporte les Common Table Expression.
    Sinon en désespoir de cause tu as la vue
    Cordialement
    Soazig

  5. #5
    Membre habitué Avatar de Orhleil
    Homme Profil pro
    Intégrateur fonctionnel
    Inscrit en
    Mai 2011
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Intégrateur fonctionnel
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 81
    Points : 152
    Points
    152
    Par défaut
    Excellent !
    Je suis parti sur ta première solution, avec un RANK(), mais la deuxième aurait pu fonctionner aussi.
    Merci beaucoup ! Va falloir que je me plonge un peu plus dans les fonctions analytiques ça a l'air pratique
    Je note en résolu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2007] Retrouver toutes les lignes qui ont une valeur identique dans la colonne A
    Par bartimeus35 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 24/06/2012, 17h47
  2. Réponses: 17
    Dernier message: 09/02/2010, 16h22
  3. Sélection de lignes qui ont des valeurs maximales
    Par sicnarf dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 31/10/2008, 15h42
  4. comment exclure les champs qui ont pour valeur NULL
    Par agur29 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 05/10/2007, 19h23
  5. Ne choisir QUE les lignes qui ont ce critere
    Par elreybubu dans le forum Oracle
    Réponses: 13
    Dernier message: 29/11/2006, 16h59

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