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

Requêtes et SQL. Discussion :

requète les 5 meilleurs résultats par catégorie


Sujet :

Requêtes et SQL.

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2
    Points : 1
    Points
    1
    Par défaut requète les 5 meilleurs résultats par catégorie
    Bonjour à tous,

    je sèche durement sur une requête et j'ai donc besoin de votre aide!

    dans une table production, je rentre des produits fabriqués par leur code CodProduit (code produit) et leur cadence CadReelle.(cadence réelle fabrication).

    à présent, j'utilise une requête selection access pour regrouper alors par CodProduit et avoir les cadences classées par ordre decroissant.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT production.CodeProduit, production.CadReelle
    FROM production
    GROUP BY production.CodeProduit, production.CadReelle
    ORDER BY production.CodeProduit, production.CadReelle DESC;

    jusque là tout va bien, sauf que ça m'affiche toutes les Cadreelle et que maintenant je voudrais selectionner que les 5 premières ( les plus grandes)
    le but final sera de faire une moyenne des 5 plus fortes cadences par produit..

    j'ai bien essayé la fonction Top 5, mais là , je n'obtient que les 5 premiers enregistrements de la table et pas les 5 cadences par produit

    je pense que ce type de requête peut servir dans de nombreux domaines, ex: les 3 meilleures ventes par pays, les 5 voitures plus économiques par marque..etc...
    si vous avez une idée, elle sera bienvenue

    merci d'avance pour votre aide.

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    bonjour,

    Essayer cette requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT Production.CodeProduit, 
           Production.CadReelle
    FROM Production
    WHERE Production.CadReelle In 
          (SELECT TOP 5 CadReelle FROM Production As P 
           WHERE P.CodeProduit=Production.CodeProduit ORDER BY P.CadReelle DESC)
    ORDER BY Production.CodeProduit, Production.CadReelle DESC;
    cordialement,

    Philippe

  3. #3
    J1
    J1 est déconnecté
    Membre averti Avatar de J1
    Inscrit en
    Mai 2004
    Messages
    321
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 321
    Points : 335
    Points
    335
    Par défaut
    Bonsoir,

    le souci de cette requête, c'est que si un produit a les CadReelles suivantes...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    600
    500
    400
    300
    200
    200
    100
    ... la requête va renvoyer pour ce produit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    600
    500
    400
    300
    200
    200
    200 sera donc en double et la moyenne que Samcool souhaite faire sera donc faite sur 6 valeurs et non 5.
    Pour éviter ce problème, il faudrait que chaque CadReelle ait un identifiant unique dans la table Production, ce qui permettrait de remanier la sous-requête corrélée afin qu'elle ne porte plus sur la CadReelle elle-même mais sur son identifiant unique.

  4. #4
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    bonjour,

    200 sera donc en double
    Une possibilité pour éviter ceci, on peut utiliser soit <Distinct> soit des <GROUP BY> :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT DISTINCT Production.CodeProduit, Production.CadReelle
    FROM Production
    WHERE Production.CadReelle In (SELECT TOP 5 CadReelle FROM Production As P 
           WHERE P.CodeProduit=Production.CodeProduit GROUP BY CadReelle ORDER BY P.CadReelle DESC)
    ORDER BY Production.CodeProduit, Production.CadReelle DESC;
    En espérant que ça réponde à votre attente.

    cordialement,

    Philippe

  5. #5
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    re bonjour,

    il reste une troisième possibilité :
    Vous souhaitez le top 5 en comptant les doublons contrairement à la requête précédente.

    Je n'ai pas trouvé de solution directe (possible ?) mais en utilisant une fonction VBA.

    Si vous souhaitez afficher aux utilisateurs les valeurs qui servent à calculer les moyennes, pour information par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT Production.CodeProduit, Production.CadReelle, Count(Production.CadReelle) AS Compte_CadReelle
    FROM Production
    WHERE Production.CadReelle In (SELECT TOP 5 CadReelle FROM Production As P 
           WHERE P.CodeProduit=Production.CodeProduit  ORDER BY P.CadReelle DESC)
    GROUP BY Production.CodeProduit, Production.CadReelle
    ORDER BY Production.CodeProduit, Production.CadReelle DESC;
    Pour calculer les moyennes avec des doublons, une solution consiste à créér une fonction VBA dans un module standard :
    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
    19
    20
    21
    22
    23
    24
    25
    26
     
    Public Function MaCadenceMoyenne(ByVal lCodeproduit As Long, ByVal iMax As Integer) As Variant
       On Error GoTo errtag
       Dim oDb As DAO.Database
       Dim oRs As DAO.Recordset
       Dim sSql As String
       Dim i As Integer
       Set oDb = CurrentDb
       sSql = "SELECT TOP 5 CadReelle FROM Production WHERE CodeProduit=" & _
              lCodeproduit & " ORDER BY CadReelle DESC"
       Set oRs = oDb.OpenRecordset(sSql, dbOpenForwardOnly)
       If Not oRs.EOF Then
          Do
             MaCadenceMoyenne = MaCadenceMoyenne + oRs(0)
             i = i + 1
             oRs.MoveNext
          Loop Until oRs.EOF Or i = iMax
          If i Then MaCadenceMoyenne = MaCadenceMoyenne / i
       End If
    fin:
       Set oRs = Nothing
       Set oDb = Nothing
       Exit Function
    errtag:
       Resume fin
    End Function
    Puis la requête qui va se servir de cette fonction pour calculer la moyenne de cadence du top 5 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT Production.CodeProduit, 
           MaCadenceMoyenne([CodeProduit],5) AS [Moyenne Top 5]
    FROM Production
    GROUP BY Production.CodeProduit;
    Y'a peut être plus simple !

    cordialement,

    philippe

  6. #6
    J1
    J1 est déconnecté
    Membre averti Avatar de J1
    Inscrit en
    Mai 2004
    Messages
    321
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 321
    Points : 335
    Points
    335
    Par défaut
    Citation Envoyé par philben
    bonjour,



    Une possibilité pour éviter ceci, on peut utiliser soit <Distinct> soit des <GROUP BY> :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT DISTINCT Production.CodeProduit, Production.CadReelle
    FROM Production
    WHERE Production.CadReelle In (SELECT TOP 5 CadReelle FROM Production As P 
           WHERE P.CodeProduit=Production.CodeProduit GROUP BY CadReelle ORDER BY P.CadReelle DESC)
    ORDER BY Production.CodeProduit, Production.CadReelle DESC;
    En espérant que ça réponde à votre attente.

    cordialement,

    Philippe
    Bonsoir,

    en faisant un regroupement à ce niveau, on se retrouvera face à un autre problème. Imaginons qu'un produit ait les CadReelles suivantes...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    600
    500
    400
    400
    300
    200
    ... le DISTINCT fera que les CadReelles conservées seront :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    600
    500
    400
    300
    On perd donc l'un des 400, alors que cette valeur fait bien partie du TOP 5 du produit.

    Mais je le répète, il suffit que Samcool ajoute un identifiant unique aux CadReelles de sa table Production pour que la requête puisse être remaniée.

  7. #7
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    re bonjour,

    Mais je le répète, il suffit que Samcool ajoute un identifiant unique aux CadReelles de sa table Production pour que la requête puisse être remaniée
    j'avais essayé cette solution mais bizarrement j'ai un top 6 qui sort pour un code produit... je ne dois pas faire la bonne requete ...

    cordialement,

    philippe

  8. #8
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Bonsoir messieurs et un très grand merci pour ce travail!

    vous avez vraiment beaucoup de ressources! c'est impressionnant.


    la 1ère solution, même si elle présente des doublons, me va bien. ces cadences sont des relevés des meilleurs moments de chaque production, sur un temps donné.
    Je cherche à extraire les cinq meilleures cadences pour avoir une idée de ce que l'on sait faire de mieux par produit fabriqué et ne pas me baser sur un maxi simplement fait une fois, ce qui serait trop optimiste.

    si il y a plusieurs cadences élevées identiques, et bien cela représente la réalité, ce qui est possible de faire au mieux, donc pas de problème pour moi.

    ainsi, je vais déjà tester cette solution.

    je vais également tester la 3ème solution, mais là, je l'avoue, il va falloir que je prenne du temps pour comprendre car c'est costaud pour mes petites connaissances informatiques!

    et dire qu'au départ, je pensais qu'il y aurait une requête toute faite dans access pour faire ça!

    encore une fois BRAVO à tous

  9. #9
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    bonjour,

    Pour info, en ajoutant la colonne ID unique la requete retournait plus de 5 valeurs à cause des doublons...
    Pour éviter ceci, il faut inclure obligatoirement la colonne ID dans le tri de la sous-requête ainsi le compte est bon.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT Production.CodeProduit,
           Production.CadReelle
    FROM Production
    WHERE Production.ID In 
          (SELECT TOP 5 ID FROM Production As P 
           WHERE P.CodeProduit=Production.CodeProduit
           ORDER BY P.id, P.CadReelle DESC)
    ORDER BY Production.CodeProduit, Production.CadReelle DESC;
    Cette solution annule et remplace la solution n°3 puisque l'on peut obtenir ainsi directement via SQL la moyenne sur TOP 5 valeurs pour chaque produit avec une deuxième requête.

    Merci à J1

    cordialement,

    Philippe

  10. #10
    J1
    J1 est déconnecté
    Membre averti Avatar de J1
    Inscrit en
    Mai 2004
    Messages
    321
    Détails du profil
    Informations forums :
    Inscription : Mai 2004
    Messages : 321
    Points : 335
    Points
    335
    Par défaut
    Citation Envoyé par philben
    bonjour,

    Pour info, en ajoutant la colonne ID unique la requete retournait plus de 5 valeurs à cause des doublons...
    Pour éviter ceci, il faut inclure obligatoirement la colonne ID dans le tri de la sous-requête ainsi le compte est bon.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT Production.CodeProduit,
           Production.CadReelle
    FROM Production
    WHERE Production.ID In 
          (SELECT TOP 5 ID FROM Production As P 
           WHERE P.CodeProduit=Production.CodeProduit
           ORDER BY P.id, P.CadReelle DESC)
    ORDER BY Production.CodeProduit, Production.CadReelle DESC;
    Bonjour,

    c'est tout à fait ça, en effet, à ceci près que l'ordre de tri dans la sous-requête doit être...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ORDER BY P.CadReelle DESC, P.id
    ... puisque l'idée est de faire un TOP 5 sur la base de P.CadReelle, puis de départager les ex-aequo de la 5e place à l'aide du P.id.

    Citation Envoyé par philben
    Merci à J1
    De rien

Discussions similaires

  1. Obtenir les 5 premiers résultats par catégorie
    Par FabFab9 dans le forum Requêtes
    Réponses: 7
    Dernier message: 06/01/2015, 15h58
  2. [MySQL] Comment Extraire les 15 meilleurs résultats
    Par Songoku77 dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 11/08/2010, 09h41
  3. [SQL SERVER 2000] Extraire le meilleur résultat par magasin
    Par casavba dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 21/02/2008, 14h13
  4. [MySQL] Avoir les 50 premiers résultat par rapport à une recherche
    Par polemoss dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 30/11/2007, 12h42
  5. [MySQL] Afficher x résultats par catégorie
    Par lorange dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 13/09/2007, 02h14

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